Commit ebe0aef2 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce

parents 109a3684 608ad7dd
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
v 7.12.0 (unreleased) v 7.12.0 (unreleased)
- Refactor permission checks with issues and merge requests project settings (Stan Hu)
- Add web hook support for note events (Stan Hu)
- Disable "New Issue" and "New Merge Request" buttons when features are disabled in project settings (Stan Hu)
- Remove Rack Attack monkey patches and bump to version 4.3.0 (Stan Hu)
- Allow to configure location of the `.gitlab_shell_secret` file. (Jakub Jirutka) - Allow to configure location of the `.gitlab_shell_secret` file. (Jakub Jirutka)
- Disabled expansion of top/bottom blobs for new file diffs - Disabled expansion of top/bottom blobs for new file diffs
- Update Asciidoctor gem to version 1.5.2. (Jakub Jirutka) - Update Asciidoctor gem to version 1.5.2. (Jakub Jirutka)
...@@ -46,7 +50,6 @@ v 7.11.0 ...@@ -46,7 +50,6 @@ v 7.11.0
- Don't crash when an MR from a fork has a cross-reference comment from the target project on one of its commits. - Don't crash when an MR from a fork has a cross-reference comment from the target project on one of its commits.
- Explain how to get a new password reset token in welcome emails - Explain how to get a new password reset token in welcome emails
- Include commit comments in MR from a forked project. - Include commit comments in MR from a forked project.
- Fix adding new group members from admin area
- Group milestones by title in the dashboard and all other issue views. - Group milestones by title in the dashboard and all other issue views.
- Query issues, merge requests and milestones with their IID through API (Julien Bianchi) - Query issues, merge requests and milestones with their IID through API (Julien Bianchi)
- Add default project and snippet visibility settings to the admin web UI. - Add default project and snippet visibility settings to the admin web UI.
......
...@@ -86,7 +86,9 @@ If you can, please submit a merge request with the fix or improvements including ...@@ -86,7 +86,9 @@ If you can, please submit a merge request with the fix or improvements including
1. If your MR touches code that executes shell commands, make sure it adheres to the [shell command guidelines]( doc/development/shell_commands.md). 1. If your MR touches code that executes shell commands, make sure it adheres to the [shell command guidelines]( doc/development/shell_commands.md).
1. Also have a look at the [shell command guidelines](doc/development/shell_commands.md) if your code reads or opens files, or handles paths to files on disk. 1. Also have a look at the [shell command guidelines](doc/development/shell_commands.md) if your code reads or opens files, or handles paths to files on disk.
The **official merge window** is in the beginning of the month from the 1st to the 7th day of the month. The best time to submit a MR and get feedback fast. Before this time the GitLab B.V. team is still dealing with work that is created by the monthly release such as assisting subscribers with upgrade issues, the release of Enterprise Edition and the upgrade of GitLab Cloud. After the 7th it is already getting closer to the release date of the next version. This means there is less time to fix the issues created by merging large new features. The **official merge window** is in the beginning of the month from the 1st to the 7th day of the month. The best time to submit a MR and get feedback fast.
Before this time the GitLab B.V. team is still dealing with work that is created by the monthly release such as regressions requiring patch releases.
After the 7th it is already getting closer to the release date of the next version. This means there is less time to fix the issues created by merging large new features.
Please keep the change in a single MR **as small as possible**. If you want to contribute a large feature think very hard what the minimum viable change is. Can you split functionality? Can you only submit the backend/API code? Can you start with a very simple UI? Can you do part of the refactor? The increased reviewability of small MR's that leads to higher code quality is more important to us than having a minimal commit log. The smaller a MR is the more likely it is it will be merged (quickly), after that you can send more MR's to enhance it. Please keep the change in a single MR **as small as possible**. If you want to contribute a large feature think very hard what the minimum viable change is. Can you split functionality? Can you only submit the backend/API code? Can you start with a very simple UI? Can you do part of the refactor? The increased reviewability of small MR's that leads to higher code quality is more important to us than having a minimal commit log. The smaller a MR is the more likely it is it will be merged (quickly), after that you can send more MR's to enhance it.
...@@ -160,8 +162,9 @@ If you add a dependency in GitLab (such as an operating system package) please c ...@@ -160,8 +162,9 @@ If you add a dependency in GitLab (such as an operating system package) please c
1. [CoffeeScript](https://github.com/thoughtbot/guides/tree/master/style#coffeescript) 1. [CoffeeScript](https://github.com/thoughtbot/guides/tree/master/style#coffeescript)
1. [Shell commands](doc/development/shell_commands.md) created by GitLab contributors to enhance security 1. [Shell commands](doc/development/shell_commands.md) created by GitLab contributors to enhance security
1. [Markdown](http://www.cirosantilli.com/markdown-styleguide) 1. [Markdown](http://www.cirosantilli.com/markdown-styleguide)
1. [Database Migrations](doc/development/migration_style_guide.md)
1. [Documentation styleguide](doc_styleguide.md)
1. Interface text should be written subjectively instead of objectively. It should be the gitlab core team addressing a person. It should be written in present time and never use past tense (has been/was). For example instead of "prohibited this user from being saved due to the following errors:" the text should be "sorry, we could not create your account because:". Also these [excellent writing guidelines](https://github.com/NARKOZ/guides#writing). 1. Interface text should be written subjectively instead of objectively. It should be the gitlab core team addressing a person. It should be written in present time and never use past tense (has been/was). For example instead of "prohibited this user from being saved due to the following errors:" the text should be "sorry, we could not create your account because:". Also these [excellent writing guidelines](https://github.com/NARKOZ/guides#writing).
1. [Migrations](doc/development/migration_style_guide.md)
This is also the style used by linting tools such as [RuboCop](https://github.com/bbatsov/rubocop), [PullReview](https://www.pullreview.com/) and [Hound CI](https://houndci.com). This is also the style used by linting tools such as [RuboCop](https://github.com/bbatsov/rubocop), [PullReview](https://www.pullreview.com/) and [Hound CI](https://houndci.com).
......
...@@ -172,7 +172,7 @@ gem "underscore-rails", "~> 1.4.4" ...@@ -172,7 +172,7 @@ gem "underscore-rails", "~> 1.4.4"
gem "sanitize", '~> 2.0' gem "sanitize", '~> 2.0'
# Protect against bruteforcing # Protect against bruteforcing
gem "rack-attack" gem "rack-attack", '~> 4.3.0'
# Ace editor # Ace editor
gem 'ace-rails-ap' gem 'ace-rails-ap'
......
...@@ -421,7 +421,7 @@ GEM ...@@ -421,7 +421,7 @@ GEM
rack (1.5.2) rack (1.5.2)
rack-accept (0.4.5) rack-accept (0.4.5)
rack (>= 0.4) rack (>= 0.4)
rack-attack (4.2.0) rack-attack (4.3.0)
rack rack
rack-cors (0.2.9) rack-cors (0.2.9)
rack-mini-profiler (0.9.0) rack-mini-profiler (0.9.0)
...@@ -764,7 +764,7 @@ DEPENDENCIES ...@@ -764,7 +764,7 @@ DEPENDENCIES
poltergeist (~> 1.5.1) poltergeist (~> 1.5.1)
pry-rails pry-rails
quiet_assets (~> 1.0.1) quiet_assets (~> 1.0.1)
rack-attack rack-attack (~> 4.3.0)
rack-cors rack-cors
rack-mini-profiler rack-mini-profiler
rack-oauth2 (~> 1.0.5) rack-oauth2 (~> 1.0.5)
......
7.11.0.pre 7.12.0.pre
\ No newline at end of file
...@@ -53,6 +53,6 @@ class Projects::HooksController < Projects::ApplicationController ...@@ -53,6 +53,6 @@ class Projects::HooksController < Projects::ApplicationController
end end
def hook_params def hook_params
params.require(:hook).permit(:url, :push_events, :issues_events, :merge_requests_events, :tag_push_events) params.require(:hook).permit(:url, :push_events, :issues_events, :merge_requests_events, :tag_push_events, :note_events)
end end
end end
...@@ -148,7 +148,7 @@ module ProjectsHelper ...@@ -148,7 +148,7 @@ module ProjectsHelper
nav_tabs << [:files, :commits, :network, :graphs] nav_tabs << [:files, :commits, :network, :graphs]
end end
if project.repo_exists? && project.merge_requests_enabled if project.repo_exists? && can?(current_user, :read_merge_request, project)
nav_tabs << :merge_requests nav_tabs << :merge_requests
end end
...@@ -156,11 +156,19 @@ module ProjectsHelper ...@@ -156,11 +156,19 @@ module ProjectsHelper
nav_tabs << :settings nav_tabs << :settings
end end
[:issues, :wiki, :snippets].each do |feature| if can?(current_user, :read_issue, project)
nav_tabs << feature if project.send :"#{feature}_enabled" nav_tabs << :issues
end end
if project.issues_enabled || project.merge_requests_enabled if can?(current_user, :read_wiki, project)
nav_tabs << :wiki
end
if can?(current_user, :read_project_snippet, project)
nav_tabs << :snippets
end
if can?(current_user, :read_milestone, project)
nav_tabs << [:milestones, :labels] nav_tabs << [:milestones, :labels]
end end
......
...@@ -101,6 +101,27 @@ class Ability ...@@ -101,6 +101,27 @@ class Ability
rules -= project_archived_rules rules -= project_archived_rules
end end
unless project.issues_enabled
rules -= named_abilities('issue')
end
unless project.merge_requests_enabled
rules -= named_abilities('merge_request')
end
unless project.issues_enabled or project.merge_requests_enabled
rules -= named_abilities('label')
rules -= named_abilities('milestone')
end
unless project.snippets_enabled
rules -= named_abilities('snippet')
end
unless project.wiki_enabled
rules -= named_abilities('wiki')
end
rules rules
end end
end end
...@@ -272,5 +293,16 @@ class Ability ...@@ -272,5 +293,16 @@ class Ability
abilities abilities
end end
end end
private
def named_abilities(name)
[
:"read_#{name}",
:"write_#{name}",
:"modify_#{name}",
:"admin_#{name}"
]
end
end end
end end
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
# issues_events :boolean default(FALSE), not null # issues_events :boolean default(FALSE), not null
# merge_requests_events :boolean default(FALSE), not null # merge_requests_events :boolean default(FALSE), not null
# tag_push_events :boolean default(FALSE) # tag_push_events :boolean default(FALSE)
# note_events :boolean default(FALSE), not null
# #
class ProjectHook < WebHook class ProjectHook < WebHook
...@@ -21,5 +22,6 @@ class ProjectHook < WebHook ...@@ -21,5 +22,6 @@ class ProjectHook < WebHook
scope :push_hooks, -> { where(push_events: true) } scope :push_hooks, -> { where(push_events: true) }
scope :tag_push_hooks, -> { where(tag_push_events: true) } scope :tag_push_hooks, -> { where(tag_push_events: true) }
scope :issue_hooks, -> { where(issues_events: true) } scope :issue_hooks, -> { where(issues_events: true) }
scope :note_hooks, -> { where(note_events: true) }
scope :merge_request_hooks, -> { where(merge_requests_events: true) } scope :merge_request_hooks, -> { where(merge_requests_events: true) }
end end
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
# issues_events :boolean default(FALSE), not null # issues_events :boolean default(FALSE), not null
# merge_requests_events :boolean default(FALSE), not null # merge_requests_events :boolean default(FALSE), not null
# tag_push_events :boolean default(FALSE) # tag_push_events :boolean default(FALSE)
# note_events :boolean default(FALSE), not null
# #
class ServiceHook < WebHook class ServiceHook < WebHook
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
# issues_events :boolean default(FALSE), not null # issues_events :boolean default(FALSE), not null
# merge_requests_events :boolean default(FALSE), not null # merge_requests_events :boolean default(FALSE), not null
# tag_push_events :boolean default(FALSE) # tag_push_events :boolean default(FALSE)
# note_events :boolean default(FALSE), not null
# #
class SystemHook < WebHook class SystemHook < WebHook
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
# issues_events :boolean default(FALSE), not null # issues_events :boolean default(FALSE), not null
# merge_requests_events :boolean default(FALSE), not null # merge_requests_events :boolean default(FALSE), not null
# tag_push_events :boolean default(FALSE) # tag_push_events :boolean default(FALSE)
# note_events :boolean default(FALSE), not null
# #
class WebHook < ActiveRecord::Base class WebHook < ActiveRecord::Base
...@@ -21,6 +22,7 @@ class WebHook < ActiveRecord::Base ...@@ -21,6 +22,7 @@ class WebHook < ActiveRecord::Base
default_value_for :push_events, true default_value_for :push_events, true
default_value_for :issues_events, false default_value_for :issues_events, false
default_value_for :note_events, false
default_value_for :merge_requests_events, false default_value_for :merge_requests_events, false
default_value_for :tag_push_events, false default_value_for :tag_push_events, false
......
...@@ -31,7 +31,7 @@ module Notes ...@@ -31,7 +31,7 @@ module Notes
def execute_hooks(note) def execute_hooks(note)
note_data = hook_data(note) note_data = hook_data(note)
# TODO: Support Webhooks note.project.execute_hooks(note_data, :note_hooks)
note.project.execute_services(note_data, :note_hooks) note.project.execute_services(note_data, :note_hooks)
end end
end end
......
- if current_user
.dropdown.pull-right
%a.dropdown-toggle.btn.btn-sm{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-bars
%ul.dropdown-menu
- if @project.issues_enabled && can?(current_user, :write_issue, @project)
%li
= link_to url_for_new_issue(@project, only_path: true), title: "New Issue" do
%i.fa.fa-fw.fa-exclamation-circle
New issue
- if @project.merge_requests_enabled && can?(current_user, :write_merge_request, @project)
%li
= link_to new_namespace_project_merge_request_path(@project.namespace, @project), title: "New Merge Request" do
%i.fa.fa-fw.fa-tasks
New merge request
- if @project.snippets_enabled && can?(current_user, :write_snippet, @project)
%li
= link_to new_namespace_project_snippet_path(@project.namespace, @project), title: "New Snippet" do
%i.fa.fa-fw.fa-file-text-o
New snippet
- if can?(current_user, :admin_project_member, @project)
%li
= link_to namespace_project_project_members_path(@project.namespace, @project), title: "New project member" do
%i.fa.fa-fw.fa-users
New project member
- if can? current_user, :push_code, @project
%li.divider
%li
= link_to new_namespace_project_branch_path(@project.namespace, @project) do
%i.fa.fa-fw.fa-code-fork
New branch
%li
= link_to new_namespace_project_tag_path(@project.namespace, @project) do
%i.fa.fa-fw.fa-tag
New tag
...@@ -34,6 +34,13 @@ ...@@ -34,6 +34,13 @@
%strong Tag push events %strong Tag push events
%p.light %p.light
This url will be triggered when a new tag is pushed to the repository This url will be triggered when a new tag is pushed to the repository
%div
= f.check_box :note_events, class: 'pull-left'
.prepend-left-20
= f.label :note_events, class: 'list-label' do
%strong Comments
%p.light
This url will be triggered when someone adds a comment
%div %div
= f.check_box :issues_events, class: 'pull-left' = f.check_box :issues_events, class: 'pull-left'
.prepend-left-20 .prepend-left-20
...@@ -64,6 +71,6 @@ ...@@ -64,6 +71,6 @@
.clearfix .clearfix
%span.monospace= hook.url %span.monospace= hook.url
%p %p
- %w(push_events tag_push_events issues_events merge_requests_events).each do |trigger| - %w(push_events tag_push_events issues_events note_events merge_requests_events).each do |trigger|
- if hook.send(trigger) - if hook.send(trigger)
%span.label.label-gray= trigger.titleize %span.label.label-gray= trigger.titleize
...@@ -61,11 +61,12 @@ ...@@ -61,11 +61,12 @@
Participants Participants
%span.badge= @users.count %span.badge= @users.count
- if @project.issues_enabled
.pull-right .pull-right
- if can?(current_user, :write_issue, @project)
= link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { milestone_id: @milestone.id }), class: "btn btn-grouped", title: "New Issue" do = link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { milestone_id: @milestone.id }), class: "btn btn-grouped", title: "New Issue" do
%i.fa.fa-plus %i.fa.fa-plus
New Issue New Issue
- if can?(current_user, :read_issue, @project)
= link_to 'Browse Issues', namespace_project_issues_path(@milestone.project.namespace, @milestone.project, milestone_id: @milestone.id), class: "btn edit-milestone-link btn-grouped" = link_to 'Browse Issues', namespace_project_issues_path(@milestone.project.namespace, @milestone.project, milestone_id: @milestone.id), class: "btn edit-milestone-link btn-grouped"
.tab-content .tab-content
......
class AddNoteEventsToWebHooks < ActiveRecord::Migration
def up
add_column :web_hooks, :note_events, :boolean, default: false, null: false
end
def down
remove_column :web_hooks, :note_events, :boolean
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150509180749) do ActiveRecord::Schema.define(version: 20150516060434) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -533,6 +533,7 @@ ActiveRecord::Schema.define(version: 20150509180749) do ...@@ -533,6 +533,7 @@ ActiveRecord::Schema.define(version: 20150509180749) do
t.boolean "issues_events", default: false, null: false t.boolean "issues_events", default: false, null: false
t.boolean "merge_requests_events", default: false, null: false t.boolean "merge_requests_events", default: false, null: false
t.boolean "tag_push_events", default: false t.boolean "tag_push_events", default: false
t.boolean "note_events", default: false, null: false
end end
add_index "web_hooks", ["created_at", "id"], name: "index_web_hooks_on_created_at_and_id", using: :btree add_index "web_hooks", ["created_at", "id"], name: "index_web_hooks_on_created_at_and_id", using: :btree
......
...@@ -71,11 +71,21 @@ do_this_and_do_that_and_another_thing ...@@ -71,11 +71,21 @@ do_this_and_do_that_and_another_thing
## URL auto-linking ## URL auto-linking
GFM will autolink standard URLs you copy and paste into your text. So if you want to link to a URL (instead of a textural link), you can simply put the URL in verbatim and it will be turned into a link to that URL. GFM will autolink almost any URL you copy and paste into your text.
http://www.google.com * http://www.google.com
* https://google.com/
http://www.google.com * ftp://ftp.us.debian.org/debian/
* smb://foo/bar/baz
* irc://irc.freenode.net/gitlab
* http://localhost:3000
* http://www.google.com
* https://google.com/
* ftp://ftp.us.debian.org/debian/
* smb://foo/bar/baz
* irc://irc.freenode.net/gitlab
* http://localhost:3000
## Code and Syntax Highlighting ## Code and Syntax Highlighting
......
...@@ -140,6 +140,285 @@ X-Gitlab-Event: Issue Hook ...@@ -140,6 +140,285 @@ X-Gitlab-Event: Issue Hook
} }
} }
``` ```
## Comment events
Triggered when a new comment is made on commits, merge requests, issues, and code snippets.
The note data will be stored in `object_attributes` (e.g. `note`, `noteable_type`). The
payload will also include information about the target of the comment. For example,
a comment on a issue will include the specific issue information under the `issue` key.
Valid target types:
1. `commit`
2. `merge_request`
3. `issue`
4. `snippet`
### Comment on commit
**Request header**:
```
X-Gitlab-Event: Note Hook
```
**Request body:**
```json
{
"object_kind": "note",
"user": {
"name": "Adminstrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"repository": {
"name": "Gitlab Test",
"url": "http://localhost/gitlab-org/gitlab-test.git",
"description": "Aut reprehenderit ut est.",
"homepage": "http://example.com/gitlab-org/gitlab-test"
},
"object_attributes": {
"id": 1243,
"note": "This is a commit comment. How does this work?",
"noteable_type": "Commit",
"author_id": 1,
"created_at": "2015-05-17 18:08:09 UTC",
"updated_at": "2015-05-17 18:08:09 UTC",
"project_id": 5,
"attachment":null,
"line_code": "bec9703f7a456cd2b4ab5fb3220ae016e3e394e3_0_1",
"commit_id": "cfe32cf61b73a0d5e9f13e774abde7ff789b1660",
"noteable_id": null,
"system": false,
"st_diff": {
"diff": "--- /dev/null\n+++ b/six\n@@ -0,0 +1 @@\n+Subproject commit 409f37c4f05865e4fb208c771485f211a22c4c2d\n",
"new_path": "six",
"old_path": "six",
"a_mode": "0",
"b_mode": "160000",
"new_file": true,
"renamed_file": false,
"deleted_file": false
},
"url": "http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660#note_1243"
},
"commit": {
"id": "cfe32cf61b73a0d5e9f13e774abde7ff789b1660",
"message": "Add submodule\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n",
"timestamp": "2014-02-27T10:06:20+02:00",
"url": "http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660",
"author": {
"name": "Dmitriy Zaporozhets",
"email": "dmitriy.zaporozhets@gmail.com"
}
}
}
```
### Comment on merge request
**Request header**:
```
X-Gitlab-Event: Note Hook
```
**Request body:**
```json
{
"object_kind": "note",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"repository": {
"name": "Gitlab Test",
"url": "http://example.com/gitlab-org/gitlab-test.git",
"description": "Aut reprehenderit ut est.",
"homepage": "http://example.com/gitlab-org/gitlab-test"
},
"object_attributes": {
"id": 1244,
"note": "This MR needs work.",
"noteable_type": "MergeRequest",
"author_id": 1,
"created_at": "2015-05-17 18:21:36 UTC",
"updated_at": "2015-05-17 18:21:36 UTC",
"project_id": 5,
"attachment": null,
"line_code": null,
"commit_id": "",
"noteable_id": 7,
"system": false,
"st_diff": null,
"url": "http://example.com/gitlab-org/gitlab-test/merge_requests/1#note_1244"
},
"merge_request": {
"id": 7,
"target_branch": "markdown",
"source_branch": "master",
"source_project_id": 5,
"author_id": 8,
"assignee_id": 28,
"title": "Tempora et eos debitis quae laborum et.",
"created_at": "2015-03-01 20:12:53 UTC",
"updated_at": "2015-03-21 18:27:27 UTC",
"milestone_id": 11,
"state": "opened",
"merge_status": "cannot_be_merged",
"target_project_id": 5,
"iid": 1,
"description": "Et voluptas corrupti assumenda temporibus. Architecto cum animi eveniet amet asperiores. Vitae numquam voluptate est natus sit et ad id.",
"position": 0,
"locked_at": null,
"source": {
"name": "Gitlab Test",
"ssh_url": "git@example.com:gitlab-org/gitlab-test.git",
"http_url": "http://example.com/gitlab-org/gitlab-test.git",
"namespace": "Gitlab Org",
"visibility_level": 10
},
"target": {
"name": "Gitlab Test",
"ssh_url": "git@example.com:gitlab-org/gitlab-test.git",
"http_url": "http://example.com/gitlab-org/gitlab-test.git",
"namespace": "Gitlab Org",
"visibility_level": 10
},
"last_commit": {
"id": "562e173be03b8ff2efb05345d12df18815438a4b",
"message": "Merge branch 'another-branch' into 'master'\n\nCheck in this test\n",
"timestamp": "2015-04-08T21: 00:25-07:00",
"url": "http://example.com/gitlab-org/gitlab-test/commit/562e173be03b8ff2efb05345d12df18815438a4b",
"author": {
"name": "John Smith",
"email": "john@example.com"
}
}
}
}
```
### Comment on issue
**Request header**:
```
X-Gitlab-Event: Note Hook
```
**Request body:**
```json
{
"object_kind": "note",
"user": {
"name": "Adminstrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"repository": {
"name": "Gitlab Test",
"url": "http://example.com/gitlab-org/gitlab-test.git",
"description": "Aut reprehenderit ut est.",
"homepage": "http://example.com/gitlab-org/gitlab-test"
},
"object_attributes": {
"id": 1241,
"note": "Hello world",
"noteable_type": "Issue",
"author_id": 1,
"created_at": "2015-05-17 17:06:40 UTC",
"updated_at": "2015-05-17 17:06:40 UTC",
"project_id": 5,
"attachment": null,
"line_code": null,
"commit_id": "",
"noteable_id": 92,
"system": false,
"st_diff": null,
"url": "http://example.com/gitlab-org/gitlab-test/issues/17#note_1241"
},
"issue": {
"id": 92,
"title": "test",
"assignee_id": null,
"author_id": 1,
"project_id": 5,
"created_at": "2015-04-12 14:53:17 UTC",
"updated_at": "2015-04-26 08:28:42 UTC",
"position": 0,
"branch_name": null,
"description": "test",
"milestone_id": null,
"state": "closed",
"iid": 17
}
}
```
### Comment on code snippet
**Request header**:
```
X-Gitlab-Event: Note Hook
```
**Request body:**
```
{
"object_kind": "note",
"user": {
"name": "Administrator",
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project_id": 5,
"repository": {
"name": "Gitlab Test",
"url": "http://example.com/gitlab-org/gitlab-test.git",
"description": "Aut reprehenderit ut est.",
"homepage": "http://example.com/gitlab-org/gitlab-test"
},
"object_attributes": {
"id": 1245,
"note": "Is this snippet doing what it's supposed to be doing?",
"noteable_type": "Snippet",
"author_id": 1,
"created_at": "2015-05-17 18:35:50 UTC",
"updated_at": "2015-05-17 18:35:50 UTC",
"project_id": 5,
"attachment": null,
"line_code": null,
"commit_id": "",
"noteable_id": 53,
"system": false,
"st_diff": null,
"url": "http://example.com/gitlab-org/gitlab-test/snippets/53#note_1245"
},
"snippet": {
"id": 53,
"title": "test",
"content": "puts 'Hello world'",
"author_id": 1,
"project_id": 5,
"created_at": "2015-04-09 02:40:38 UTC",
"updated_at": "2015-04-09 02:40:38 UTC",
"file_name": "test.rb",
"expires_at": null,
"type": "ProjectSnippet",
"visibility_level": 0
}
}
```
## Merge request events ## Merge request events
......
# Documentation styleguide
This styleguide recommends best practices to improve documentation and to keep it organized and easy to find.
## Text
* Make sure that the documentation is added in the correct directory and that there's a link to it somewhere useful.
* Add only one H1 or title in each document, by adding '#' at the begining of it (when using markdown). For subtitles, use '##', '###' and so on.
* Do not duplicate information.
* Be brief and clear.
## When adding images to a document
* Create a directory to store the images with the specific name of the document where the images belong. It could be in the same directory where the .md document that you're working on is located.
* Images should have a specific, non-generic name that will differentiate them.
* Keep all file names in lower case.
\ No newline at end of file
...@@ -62,3 +62,9 @@ Feature: Project ...@@ -62,3 +62,9 @@ Feature: Project
And I add project tags And I add project tags
And I save project And I save project
Then I should see project tags Then I should see project tags
Scenario: I should not see "New Issue" or "New Merge Request" buttons
Given I disable issues and merge requests in project
When I visit project "Shop" page
Then I should not see "New Issue" button
And I should not see "New Merge Request" button
...@@ -102,4 +102,12 @@ class Spinach::Features::Project < Spinach::FeatureSteps ...@@ -102,4 +102,12 @@ class Spinach::Features::Project < Spinach::FeatureSteps
step 'I should see project tags' do step 'I should see project tags' do
expect(find_field('Tags').value).to eq 'tag1, tag2' expect(find_field('Tags').value).to eq 'tag1, tag2'
end end
step 'I should not see "New Issue" button' do
page.should_not have_link 'New Issue'
end
step 'I should not see "New Merge Request" button' do
page.should_not have_link 'New Merge Request'
end
end end
...@@ -14,6 +14,12 @@ module SharedProject ...@@ -14,6 +14,12 @@ module SharedProject
@project.team << [@user, :master] @project.team << [@user, :master]
end end
step 'I disable issues and merge requests in project' do
@project.issues_enabled = false
@project.merge_requests_enabled = false
@project.save
end
# Add another user to project "Shop" # Add another user to project "Shop"
step 'I add a user to project "Shop"' do step 'I add a user to project "Shop"' do
@project = Project.find_by(name: "Shop") @project = Project.find_by(name: "Shop")
......
...@@ -43,7 +43,8 @@ module API ...@@ -43,7 +43,8 @@ module API
:push_events, :push_events,
:issues_events, :issues_events,
:merge_requests_events, :merge_requests_events,
:tag_push_events :tag_push_events,
:note_events
] ]
@hook = user_project.hooks.new(attrs) @hook = user_project.hooks.new(attrs)
...@@ -73,7 +74,8 @@ module API ...@@ -73,7 +74,8 @@ module API
:push_events, :push_events,
:issues_events, :issues_events,
:merge_requests_events, :merge_requests_events,
:tag_push_events :tag_push_events,
:note_events
] ]
if @hook.update_attributes attrs if @hook.update_attributes attrs
......
require_relative 'rack_attack_helpers'
require_relative 'shell_env' require_relative 'shell_env'
module Grack module Grack
......
# rack-attack v4.2.0 doesn't yet support clearing of keys.
# Taken from https://github.com/kickstarter/rack-attack/issues/113
class Rack::Attack::Allow2Ban
def self.reset(discriminator, options)
findtime = options[:findtime] or raise ArgumentError, "Must pass findtime option"
cache.reset_count("#{key_prefix}:count:#{discriminator}", findtime)
cache.delete("#{key_prefix}:ban:#{discriminator}")
end
end
class Rack::Attack::Cache
def reset_count(unprefixed_key, period)
epoch_time = Time.now.to_i
# Add 1 to expires_in to avoid timing error: http://git.io/i1PHXA
expires_in = period - (epoch_time % period) + 1
key = "#{(epoch_time / period).to_i}:#{unprefixed_key}"
delete(key)
end
def delete(unprefixed_key)
store.delete("#{prefix}:#{unprefixed_key}")
end
end
class Rack::Attack::StoreProxy::RedisStoreProxy
def delete(key, options={})
self.del(key)
rescue Redis::BaseError
end
end
...@@ -156,7 +156,7 @@ describe Grack::Auth do ...@@ -156,7 +156,7 @@ describe Grack::Auth do
end end
expect(attempt_login(true)).to eq(200) expect(attempt_login(true)).to eq(200)
expect(Rack::Attack::Allow2Ban.send(:banned?, ip)).to eq(nil) expect(Rack::Attack::Allow2Ban.banned?(ip)).to be_falsey
for n in 0..maxretry do for n in 0..maxretry do
expect(attempt_login(false)).to eq(401) expect(attempt_login(false)).to eq(401)
......
require "spec_helper"
describe 'RackAttackHelpers' do
describe 'reset' do
let(:discriminator) { 'test-key'}
let(:maxretry) { 5 }
let(:period) { 1.minute }
let(:options) { { findtime: period, bantime: 60, maxretry: maxretry } }
def do_filter
for i in 1..maxretry - 1 do
status = Rack::Attack::Allow2Ban.filter(discriminator, options) { true }
expect(status).to eq(false)
end
end
def do_reset
Rack::Attack::Allow2Ban.reset(discriminator, options)
end
before do
do_reset
end
after do
do_reset
end
it 'user is not banned after n - 1 retries' do
do_filter
do_reset
do_filter
end
end
end
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
# issues_events :boolean default(FALSE), not null # issues_events :boolean default(FALSE), not null
# merge_requests_events :boolean default(FALSE), not null # merge_requests_events :boolean default(FALSE), not null
# tag_push_events :boolean default(FALSE) # tag_push_events :boolean default(FALSE)
# note_events :boolean default(FALSE), not null
# #
require 'spec_helper' require 'spec_helper'
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
# issues_events :boolean default(FALSE), not null # issues_events :boolean default(FALSE), not null
# merge_requests_events :boolean default(FALSE), not null # merge_requests_events :boolean default(FALSE), not null
# tag_push_events :boolean default(FALSE) # tag_push_events :boolean default(FALSE)
# note_events :boolean default(FALSE), not null
# #
require "spec_helper" require "spec_helper"
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
# issues_events :boolean default(FALSE), not null # issues_events :boolean default(FALSE), not null
# merge_requests_events :boolean default(FALSE), not null # merge_requests_events :boolean default(FALSE), not null
# tag_push_events :boolean default(FALSE) # tag_push_events :boolean default(FALSE)
# note_events :boolean default(FALSE), not null
# #
require "spec_helper" require "spec_helper"
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
# issues_events :boolean default(FALSE), not null # issues_events :boolean default(FALSE), not null
# merge_requests_events :boolean default(FALSE), not null # merge_requests_events :boolean default(FALSE), not null
# tag_push_events :boolean default(FALSE) # tag_push_events :boolean default(FALSE)
# note_events :boolean default(FALSE), not null
# #
require 'spec_helper' require 'spec_helper'
......
...@@ -15,6 +15,8 @@ describe Notes::CreateService do ...@@ -15,6 +15,8 @@ describe Notes::CreateService do
noteable_id: issue.id noteable_id: issue.id
} }
expect(project).to receive(:execute_hooks)
expect(project).to receive(:execute_services)
@note = Notes::CreateService.new(project, user, opts).execute @note = Notes::CreateService.new(project, user, opts).execute
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