summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG19
-rw-r--r--GITLAB_SHELL_VERSION2
-rw-r--r--app/assets/javascripts/dispatcher.js.coffee2
-rw-r--r--app/assets/javascripts/team_members.js.coffee4
-rw-r--r--app/assets/stylesheets/highlight/white.scss8
-rw-r--r--app/controllers/projects/base_tree_controller.rb1
-rw-r--r--app/controllers/projects/blame_controller.rb1
-rw-r--r--app/controllers/projects/blob_controller.rb1
-rw-r--r--app/controllers/projects/branches_controller.rb6
-rw-r--r--app/controllers/projects/commit_controller.rb1
-rw-r--r--app/controllers/projects/commits_controller.rb1
-rw-r--r--app/controllers/projects/compare_controller.rb1
-rw-r--r--app/controllers/projects/graphs_controller.rb1
-rw-r--r--app/controllers/projects/network_controller.rb1
-rw-r--r--app/controllers/projects/raw_controller.rb1
-rw-r--r--app/controllers/projects/refs_controller.rb1
-rw-r--r--app/controllers/projects/repositories_controller.rb1
-rw-r--r--app/controllers/projects/tags_controller.rb2
-rw-r--r--app/controllers/projects_controller.rb1
-rw-r--r--app/helpers/commits_helper.rb8
-rw-r--r--app/helpers/emails_helper.rb32
-rw-r--r--app/helpers/issues_helper.rb13
-rw-r--r--app/helpers/projects_helper.rb4
-rw-r--r--app/mailers/notify.rb1
-rw-r--r--app/models/note.rb35
-rw-r--r--app/models/project.rb39
-rw-r--r--app/models/project_services/flowdock_service.rb3
-rw-r--r--app/models/project_services/gemnasium_service.rb3
-rw-r--r--app/models/project_services/gitlab_ci_service.rb4
-rw-r--r--app/services/git_push_service.rb18
-rw-r--r--app/services/merge_requests/refresh_service.rb67
-rw-r--r--app/views/layouts/notify.html.haml1
-rw-r--r--app/views/projects/issues/show.html.haml2
-rw-r--r--app/views/projects/merge_requests/show/_how_to_merge.html.haml6
-rw-r--r--app/views/projects/new_tree/show.html.haml4
-rw-r--r--app/views/projects/notes/_note.html.haml2
-rw-r--r--app/views/projects/team_members/_team_member.html.haml2
-rw-r--r--db/fixtures/production/001_admin.rb14
-rw-r--r--doc/README.md1
-rw-r--r--doc/api/commits.md63
-rw-r--r--doc/hooks/custom_hooks.md41
-rw-r--r--doc/install/requirements.md7
-rw-r--r--doc/integration/gitlab_actions.pngbin0 -> 17321 bytes
-rw-r--r--doc/integration/gitlab_buttons_in_gmail.md11
-rw-r--r--doc/release/monthly.md83
-rw-r--r--doc/release/patch.md31
-rw-r--r--doc/update/upgrader.md17
-rw-r--r--lib/api/commits.rb61
-rw-r--r--lib/api/entities.rb8
-rw-r--r--lib/backup/database.rb1
-rw-r--r--lib/backup/repository.rb10
-rw-r--r--lib/gitlab/backend/shell.rb7
-rw-r--r--lib/gitlab/git_ref_validator.rb2
-rw-r--r--lib/gitlab/utils.rb5
-rw-r--r--lib/support/nginx/gitlab10
-rw-r--r--lib/support/nginx/gitlab-ssl30
-rw-r--r--lib/tasks/gitlab/check.rake10
-rw-r--r--lib/tasks/gitlab/cleanup.rake4
-rw-r--r--lib/tasks/gitlab/db/drop_all_postgres_sequences.rake10
-rw-r--r--lib/tasks/gitlab/shell.rake4
-rw-r--r--spec/controllers/branches_controller_spec.rb51
-rw-r--r--spec/models/gitlab_ci_service_spec.rb4
-rw-r--r--spec/models/note_spec.rb6
-rw-r--r--spec/models/project_spec.rb57
-rw-r--r--spec/requests/api/commits_spec.rb65
-rw-r--r--spec/requests/api/projects_spec.rb6
-rw-r--r--spec/requests/api/repositories_spec.rb3
-rw-r--r--spec/requests/api/users_spec.rb6
-rw-r--r--spec/services/merge_requests/refresh_service_spec.rb98
69 files changed, 752 insertions, 273 deletions
diff --git a/CHANGELOG b/CHANGELOG
index ff41575bcc6..d27ec2bbe29 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,12 +3,31 @@ v 7.5.0
- Add time zone configuration on gitlab.yml (Sullivan Senechal)
- Fix LDAP authentication for Git HTTP access
- Fix LDAP config lookup for provider 'ldap'
+ - Drop all sequences during Postgres database restore
+ - Project title links to project homepage (Ben Bodenmiller)
- Add Atlassian Bamboo CI service (Drew Blessing)
- Mentioned @user will receive email even if he is not participating in issue or commit
- Session API: Use case-insensitive authentication like in UI (Andrey Krivko)
- Tie up loose ends with annotated tags: API & UI (Sean Edge)
- Return valid json for deleting branch via API (sponsored by O'Reilly Media)
- Expose username in project events API (sponsored by O'Reilly Media)
+ - Adds comments to commits in the API
+ - Performance improvements
+ - Fix post-receive issue for projects with deleted forks
+ - New gitlab-shell version with custom hooks support
+ - Improve code
+ - GitLab CI 5.2+ support (does not support older versions)
+ - Fixed bug when you can not push commits starting with 000000 to protected branches
+ - Added a password strength indicator
+ - Change project name and path in one form
+ - Display renamed files in diff views (Vinnie Okada)
+ - Add timezone configuration to gitlab.yml
+ - Fix raw view for public snippets
+
+v 7.4.3
+ - Fix raw snippets view
+ - Fix security issue for member api
+ - Fix buildbox integration
v 7.4.2
- Fix internal snippet exposing for unauthenticated users
diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION
index 7ec1d6db408..ccbccc3dc62 100644
--- a/GITLAB_SHELL_VERSION
+++ b/GITLAB_SHELL_VERSION
@@ -1 +1 @@
-2.1.0
+2.2.0
diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee
index ec4b7ea42cf..fb1adbc4b3d 100644
--- a/app/assets/javascripts/dispatcher.js.coffee
+++ b/app/assets/javascripts/dispatcher.js.coffee
@@ -58,8 +58,6 @@ class Dispatcher
when 'groups:show', 'projects:show'
new Activities()
shortcut_handler = new ShortcutsNavigation()
- when 'projects:teams:members:index'
- new TeamMembers()
when 'groups:members'
new GroupMembers()
new UsersSelect()
diff --git a/app/assets/javascripts/team_members.js.coffee b/app/assets/javascripts/team_members.js.coffee
deleted file mode 100644
index 32486f7da54..00000000000
--- a/app/assets/javascripts/team_members.js.coffee
+++ /dev/null
@@ -1,4 +0,0 @@
-class @TeamMembers
- constructor: ->
- $('.team-members .project-access-select').on "change", ->
- $(this.form).submit()
diff --git a/app/assets/stylesheets/highlight/white.scss b/app/assets/stylesheets/highlight/white.scss
index 815cf367ae8..8d5822937a0 100644
--- a/app/assets/stylesheets/highlight/white.scss
+++ b/app/assets/stylesheets/highlight/white.scss
@@ -186,3 +186,11 @@
}
}
}
+
+.readme-holder .wiki, .note-body, .wiki-holder {
+ .white {
+ .highlight, pre, .hljs {
+ background: #F9F9F9;
+ }
+ }
+}
diff --git a/app/controllers/projects/base_tree_controller.rb b/app/controllers/projects/base_tree_controller.rb
index 56c306063c8..a7b1b7b40e8 100644
--- a/app/controllers/projects/base_tree_controller.rb
+++ b/app/controllers/projects/base_tree_controller.rb
@@ -1,7 +1,6 @@
class Projects::BaseTreeController < Projects::ApplicationController
include ExtractsPath
- before_filter :authorize_read_project!
before_filter :authorize_download_code!
before_filter :require_non_empty_project
end
diff --git a/app/controllers/projects/blame_controller.rb b/app/controllers/projects/blame_controller.rb
index bad06e7aa2d..367d1295f34 100644
--- a/app/controllers/projects/blame_controller.rb
+++ b/app/controllers/projects/blame_controller.rb
@@ -3,7 +3,6 @@ class Projects::BlameController < Projects::ApplicationController
include ExtractsPath
# Authorize
- before_filter :authorize_read_project!
before_filter :authorize_download_code!
before_filter :require_non_empty_project
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index 04aa044001e..2412800c493 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -3,7 +3,6 @@ class Projects::BlobController < Projects::ApplicationController
include ExtractsPath
# Authorize
- before_filter :authorize_read_project!
before_filter :authorize_download_code!
before_filter :require_non_empty_project
before_filter :authorize_push_code!, only: [:destroy]
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index 9f50660a5ad..cff1a907dc2 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -1,6 +1,6 @@
class Projects::BranchesController < Projects::ApplicationController
+ include ActionView::Helpers::SanitizeHelper
# Authorize
- before_filter :authorize_read_project!
before_filter :require_non_empty_project
before_filter :authorize_download_code!
@@ -17,8 +17,10 @@ class Projects::BranchesController < Projects::ApplicationController
end
def create
+ branch_name = sanitize(strip_tags(params[:branch_name]))
+ ref = sanitize(strip_tags(params[:ref]))
result = CreateBranchService.new(project, current_user).
- execute(params[:branch_name], params[:ref])
+ execute(branch_name, ref)
if result[:status] == :success
@branch = result[:branch]
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index cf05e6ea220..dac858d8e16 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -3,7 +3,6 @@
# Not to be confused with CommitsController, plural.
class Projects::CommitController < Projects::ApplicationController
# Authorize
- before_filter :authorize_read_project!
before_filter :authorize_download_code!
before_filter :require_non_empty_project
before_filter :commit
diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb
index 53a0d063d8e..9476b6c0284 100644
--- a/app/controllers/projects/commits_controller.rb
+++ b/app/controllers/projects/commits_controller.rb
@@ -4,7 +4,6 @@ class Projects::CommitsController < Projects::ApplicationController
include ExtractsPath
# Authorize
- before_filter :authorize_read_project!
before_filter :authorize_download_code!
before_filter :require_non_empty_project
diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb
index 6d944025598..ffb8c2e4af1 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -1,6 +1,5 @@
class Projects::CompareController < Projects::ApplicationController
# Authorize
- before_filter :authorize_read_project!
before_filter :authorize_download_code!
before_filter :require_non_empty_project
diff --git a/app/controllers/projects/graphs_controller.rb b/app/controllers/projects/graphs_controller.rb
index 21d3970d65a..4a318cb7d56 100644
--- a/app/controllers/projects/graphs_controller.rb
+++ b/app/controllers/projects/graphs_controller.rb
@@ -1,6 +1,5 @@
class Projects::GraphsController < Projects::ApplicationController
# Authorize
- before_filter :authorize_read_project!
before_filter :authorize_download_code!
before_filter :require_non_empty_project
diff --git a/app/controllers/projects/network_controller.rb b/app/controllers/projects/network_controller.rb
index 009089ee639..ada1aed0df7 100644
--- a/app/controllers/projects/network_controller.rb
+++ b/app/controllers/projects/network_controller.rb
@@ -3,7 +3,6 @@ class Projects::NetworkController < Projects::ApplicationController
include ApplicationHelper
# Authorize
- before_filter :authorize_read_project!
before_filter :authorize_download_code!
before_filter :require_non_empty_project
diff --git a/app/controllers/projects/raw_controller.rb b/app/controllers/projects/raw_controller.rb
index f4fdd616c50..fdbc4c5a098 100644
--- a/app/controllers/projects/raw_controller.rb
+++ b/app/controllers/projects/raw_controller.rb
@@ -3,7 +3,6 @@ class Projects::RawController < Projects::ApplicationController
include ExtractsPath
# Authorize
- before_filter :authorize_read_project!
before_filter :authorize_download_code!
before_filter :require_non_empty_project
diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb
index 9ac189a78b3..5d9336bdc49 100644
--- a/app/controllers/projects/refs_controller.rb
+++ b/app/controllers/projects/refs_controller.rb
@@ -2,7 +2,6 @@ class Projects::RefsController < Projects::ApplicationController
include ExtractsPath
# Authorize
- before_filter :authorize_read_project!
before_filter :authorize_download_code!
before_filter :require_non_empty_project
diff --git a/app/controllers/projects/repositories_controller.rb b/app/controllers/projects/repositories_controller.rb
index 6d8ef0f1ac8..bcd14a1c847 100644
--- a/app/controllers/projects/repositories_controller.rb
+++ b/app/controllers/projects/repositories_controller.rb
@@ -1,6 +1,5 @@
class Projects::RepositoriesController < Projects::ApplicationController
# Authorize
- before_filter :authorize_read_project!
before_filter :authorize_download_code!
before_filter :require_non_empty_project
diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb
index 94794fb5dd0..162ddef0fec 100644
--- a/app/controllers/projects/tags_controller.rb
+++ b/app/controllers/projects/tags_controller.rb
@@ -1,8 +1,6 @@
class Projects::TagsController < Projects::ApplicationController
# Authorize
- before_filter :authorize_read_project!
before_filter :require_non_empty_project
-
before_filter :authorize_download_code!
before_filter :authorize_push_code!, only: [:create]
before_filter :authorize_admin_project!, only: [:destroy]
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 360894c7639..b5910c902e4 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -4,7 +4,6 @@ class ProjectsController < ApplicationController
before_filter :repository, except: [:new, :create]
# Authorize
- before_filter :authorize_read_project!, except: [:index, :new, :create]
before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive, :retry_import]
layout 'navless', only: [:new, :create, :fork]
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index 0e0532b65b2..36adeadd8a5 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -87,8 +87,8 @@ module CommitsHelper
# avatar: true will prepend the avatar image
# size: size of the avatar image in px
def commit_person_link(commit, options = {})
- source_name = commit.send "#{options[:source]}_name".to_sym
- source_email = commit.send "#{options[:source]}_email".to_sym
+ source_name = clean(commit.send "#{options[:source]}_name".to_sym)
+ source_email = clean(commit.send "#{options[:source]}_email".to_sym)
user = User.find_for_commit(source_email, source_name)
person_name = user.nil? ? source_name : user.name
@@ -124,4 +124,8 @@ module CommitsHelper
def truncate_sha(sha)
Commit.truncate_sha(sha)
end
+
+ def clean(string)
+ Sanitize.clean(string, remove_contents: true)
+ end
end
diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb
new file mode 100644
index 00000000000..24d67c21d6b
--- /dev/null
+++ b/app/helpers/emails_helper.rb
@@ -0,0 +1,32 @@
+module EmailsHelper
+
+ # Google Actions
+ # https://developers.google.com/gmail/markup/reference/go-to-action
+ def email_action(url)
+ name = action_title(url)
+ if name
+ data = {
+ "@context" => "http://schema.org",
+ "@type" => "EmailMessage",
+ "action" => {
+ "@type" => "ViewAction",
+ "name" => name,
+ "url" => url,
+ }
+ }
+
+ content_tag :script, type: 'application/ld+json' do
+ data.to_json.html_safe
+ end
+ end
+ end
+
+ def action_title(url)
+ return unless url
+ ["merge_requests", "issues", "commit"].each do |action|
+ if url.split("/").include?(action)
+ return "View #{action.humanize.singularize}"
+ end
+ end
+ end
+end
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 7671033b539..d513e0ba58e 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -62,6 +62,19 @@ module IssuesHelper
''
end
+ def issue_timestamp(issue)
+ # Shows the created at time and the updated at time if different
+ ts = "#{time_ago_with_tooltip(issue.created_at, 'bottom', 'note_created_ago')}"
+ if issue.updated_at != issue.created_at
+ ts << capture_haml do
+ haml_tag :small do
+ haml_concat " (Edited #{time_ago_with_tooltip(issue.updated_at, 'bottom', 'issue_edited_ago')})"
+ end
+ end
+ end
+ ts.html_safe
+ end
+
# Checks if issues_tracker setting exists in gitlab.yml
def external_issues_tracker_enabled?
Gitlab.config.issues_tracker && Gitlab.config.issues_tracker.values.any?
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 883c1f63af6..fb5470d98e5 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -42,12 +42,12 @@ module ProjectsHelper
def project_title(project)
if project.group
content_tag :span do
- link_to(simple_sanitize(project.group.name), group_path(project.group)) + " / " + project.name
+ link_to(simple_sanitize(project.group.name), group_path(project.group)) + ' / ' + link_to(simple_sanitize(project.name), project_path(project))
end
else
owner = project.namespace.owner
content_tag :span do
- link_to(simple_sanitize(owner.name), user_path(owner)) + " / " + project.name
+ link_to(simple_sanitize(owner.name), user_path(owner)) + ' / ' + link_to(simple_sanitize(project.name), project_path(project))
end
end
end
diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb
index bd438bab89a..0ee19836627 100644
--- a/app/mailers/notify.rb
+++ b/app/mailers/notify.rb
@@ -11,6 +11,7 @@ class Notify < ActionMailer::Base
add_template_helper ApplicationHelper
add_template_helper GitlabMarkdownHelper
add_template_helper MergeRequestsHelper
+ add_template_helper EmailsHelper
default_url_options[:host] = Gitlab.config.gitlab.host
default_url_options[:protocol] = Gitlab.config.gitlab.protocol
diff --git a/app/models/note.rb b/app/models/note.rb
index f0ed7580b4c..5bf645bbd1d 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -90,7 +90,7 @@ class Note < ActiveRecord::Base
note_options.merge!(noteable: noteable)
end
- create(note_options)
+ create(note_options) unless cross_reference_disallowed?(noteable, mentioner)
end
def create_milestone_change_note(noteable, project, author, milestone)
@@ -165,6 +165,15 @@ class Note < ActiveRecord::Base
[:discussion, type.try(:underscore), id, line_code].join("-").to_sym
end
+ # Determine if cross reference note should be created.
+ # eg. mentioning a commit in MR comments which exists inside a MR
+ # should not create "mentioned in" note.
+ def cross_reference_disallowed?(noteable, mentioner)
+ if mentioner.kind_of?(MergeRequest)
+ mentioner.commits.map(&:id).include? noteable.id
+ end
+ end
+
# Determine whether or not a cross-reference note already exists.
def cross_reference_exists?(noteable, mentioner)
gfm_reference = mentioner_gfm_ref(noteable, mentioner)
@@ -251,8 +260,8 @@ class Note < ActiveRecord::Base
def commit_author
@commit_author ||=
- project.users.find_by(email: noteable.author_email) ||
- project.users.find_by(name: noteable.author_name)
+ project.team.users.find_by(email: noteable.author_email) ||
+ project.team.users.find_by(name: noteable.author_name)
rescue
nil
end
@@ -308,7 +317,7 @@ class Note < ActiveRecord::Base
end
def diff_file_index
- line_code.split('_')[0]
+ line_code.split('_')[0] if line_code
end
def diff_file_name
@@ -324,11 +333,11 @@ class Note < ActiveRecord::Base
end
def diff_old_line
- line_code.split('_')[1].to_i
+ line_code.split('_')[1].to_i if line_code
end
def diff_new_line
- line_code.split('_')[2].to_i
+ line_code.split('_')[2].to_i if line_code
end
def generate_line_code(line)
@@ -349,6 +358,20 @@ class Note < ActiveRecord::Base
@diff_line
end
+ def diff_line_type
+ return @diff_line_type if @diff_line_type
+
+ if diff
+ diff_lines.each do |line|
+ if generate_line_code(line) == self.line_code
+ @diff_line_type = line.type
+ end
+ end
+ end
+
+ @diff_line_type
+ end
+
def truncated_diff_lines
max_number_of_lines = 16
prev_match_line = nil
diff --git a/app/models/project.rb b/app/models/project.rb
index c58c9b551c9..d2576bb85d0 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -402,43 +402,8 @@ class Project < ActiveRecord::Base
end
def update_merge_requests(oldrev, newrev, ref, user)
- return true unless ref =~ /heads/
- branch_name = ref.gsub("refs/heads/", "")
- commits = self.repository.commits_between(oldrev, newrev)
- c_ids = commits.map(&:id)
-
- # Close merge requests
- mrs = self.merge_requests.opened.where(target_branch: branch_name).to_a
- mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
-
- mrs.uniq.each do |merge_request|
- MergeRequests::MergeService.new.execute(merge_request, user, nil)
- end
-
- # Update code for merge requests into project between project branches
- mrs = self.merge_requests.opened.by_branch(branch_name).to_a
- # Update code for merge requests between project and project fork
- mrs += self.fork_merge_requests.opened.by_branch(branch_name).to_a
-
- mrs.uniq.each do |merge_request|
- merge_request.reload_code
- merge_request.mark_as_unchecked
- end
-
- # Add comment about pushing new commits to merge requests
- comment_mr_with_commits(branch_name, commits, user)
-
- true
- end
-
- def comment_mr_with_commits(branch_name, commits, user)
- mrs = self.origin_merge_requests.opened.where(source_branch: branch_name).to_a
- mrs += self.fork_merge_requests.opened.where(source_branch: branch_name).to_a
-
- mrs.uniq.each do |merge_request|
- Note.create_new_commits_note(merge_request, merge_request.project,
- user, commits)
- end
+ MergeRequests::RefreshService.new(self, user).
+ execute(oldrev, newrev, ref)
end
def valid_repo?
diff --git a/app/models/project_services/flowdock_service.rb b/app/models/project_services/flowdock_service.rb
index 0020b4482e5..86705f5dabd 100644
--- a/app/models/project_services/flowdock_service.rb
+++ b/app/models/project_services/flowdock_service.rb
@@ -37,13 +37,12 @@ class FlowdockService < Service
end
def execute(push_data)
- repo_path = File.join(Gitlab.config.gitlab_shell.repos_path, "#{project.path_with_namespace}.git")
Flowdock::Git.post(
push_data[:ref],
push_data[:before],
push_data[:after],
token: token,
- repo: repo_path,
+ repo: project.repository.path_to_repo,
repo_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}",
commit_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/commit/%s",
diff_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/compare/%s...%s",
diff --git a/app/models/project_services/gemnasium_service.rb b/app/models/project_services/gemnasium_service.rb
index 6d2fc06a5d0..18fdd204ecd 100644
--- a/app/models/project_services/gemnasium_service.rb
+++ b/app/models/project_services/gemnasium_service.rb
@@ -38,14 +38,13 @@ class GemnasiumService < Service
end
def execute(push_data)
- repo_path = File.join(Gitlab.config.gitlab_shell.repos_path, "#{project.path_with_namespace}.git")
Gemnasium::GitlabService.execute(
ref: push_data[:ref],
before: push_data[:before],
after: push_data[:after],
token: token,
api_key: api_key,
- repo: repo_path
+ repo: project.repository.path_to_repo
)
end
end
diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb
index a897c4ab76b..fadebf968bc 100644
--- a/app/models/project_services/gitlab_ci_service.rb
+++ b/app/models/project_services/gitlab_ci_service.rb
@@ -28,7 +28,7 @@ class GitlabCiService < CiService
end
def commit_status_path(sha)
- project_url + "/builds/#{sha}/status.json?token=#{token}"
+ project_url + "/commits/#{sha}/status.json?token=#{token}"
end
def get_ci_build(sha)
@@ -55,7 +55,7 @@ class GitlabCiService < CiService
end
def build_page(sha)
- project_url + "/builds/#{sha}"
+ project_url + "/commits/#{sha}"
end
def builds_path
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index 3f5222c93f1..529af1970f6 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -83,9 +83,14 @@ class GitPushService
# closing regex. Exclude any mentioned Issues from cross-referencing even if the commits are being pushed to
# a different branch.
issues_to_close = commit.closes_issues(project)
- author = commit_user(commit)
- if !issues_to_close.empty? && is_default_branch
+ # Load commit author only if needed.
+ # For push with 1k commits it prevents 900+ requests in database
+ author = nil
+
+ if issues_to_close.present? && is_default_branch
+ author ||= commit_user(commit)
+
issues_to_close.each do |issue|
Issues::CloseService.new(project, author, {}).execute(issue, commit)
end
@@ -96,8 +101,13 @@ class GitPushService
# being pushed to a different branch).
refs = commit.references(project) - issues_to_close
refs.reject! { |r| commit.has_mentioned?(r) }
- refs.each do |r|
- Note.create_cross_reference_note(r, commit, author, project)
+
+ if refs.present?
+ author ||= commit_user(commit)
+
+ refs.each do |r|
+ Note.create_cross_reference_note(r, commit, author, project)
+ end
end
end
end
diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb
new file mode 100644
index 00000000000..74448998ddd
--- /dev/null
+++ b/app/services/merge_requests/refresh_service.rb
@@ -0,0 +1,67 @@
+module MergeRequests
+ class RefreshService < MergeRequests::BaseService
+ def execute(oldrev, newrev, ref)
+ return true unless ref =~ /heads/
+
+ @branch_name = ref.gsub("refs/heads/", "")
+ @fork_merge_requests = @project.fork_merge_requests.opened
+ @commits = @project.repository.commits_between(oldrev, newrev)
+
+ close_merge_requests
+ reload_merge_requests
+ comment_mr_with_commits
+
+ true
+ end
+
+ private
+
+ # Collect open merge requests that target same branch we push into
+ # and close if push to master include last commit from merge request
+ # We need this to close(as merged) merge requests that were merged into
+ # target branch manually
+ def close_merge_requests
+ commit_ids = @commits.map(&:id)
+ merge_requests = @project.merge_requests.opened.where(target_branch: @branch_name).to_a
+ merge_requests = merge_requests.select(&:last_commit)
+
+ merge_requests = merge_requests.select do |merge_request|
+ commit_ids.include?(merge_request.last_commit.id)
+ end
+
+
+ merge_requests.uniq.select(&:source_project).each do |merge_request|
+ MergeRequests::MergeService.new.execute(merge_request, @current_user, nil)
+ end
+ end
+
+ # Refresh merge request diff if we push to source or target branch of merge request
+ # Note: we should update merge requests from forks too
+ def reload_merge_requests
+ merge_requests = @project.merge_requests.opened.by_branch(@branch_name).to_a
+ merge_requests += @fork_merge_requests.by_branch(@branch_name).to_a
+ merge_requests = filter_merge_requests(merge_requests)
+
+ merge_requests.each do |merge_request|
+ merge_request.reload_code
+ merge_request.mark_as_unchecked
+ end
+ end
+
+ # Add comment about pushing new commits to merge requests
+ def comment_mr_with_commits
+ merge_requests = @project.origin_merge_requests.opened.where(source_branch: @branch_name).to_a
+ merge_requests += @fork_merge_requests.where(source_branch: @branch_name).to_a
+ merge_requests = filter_merge_requests(merge_requests)
+
+ merge_requests.each do |merge_request|
+ Note.create_new_commits_note(merge_request, merge_request.project,
+ @current_user, @commits)
+ end
+ end
+
+ def filter_merge_requests(merge_requests)
+ merge_requests.uniq.select(&:source_project)
+ end
+ end
+end
diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml
index ab421d63f1a..da451961327 100644
--- a/app/views/layouts/notify.html.haml
+++ b/app/views/layouts/notify.html.haml
@@ -28,3 +28,4 @@
You're receiving this notification because you are a member of the #{link_to_unless @target_url, @project.name_with_namespace, project_url(@project)} project team.
- if @target_url
#{link_to "View it on GitLab", @target_url}
+ = email_action @target_url
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index 71eb0d5c866..aad58e48f6c 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -39,7 +39,7 @@
Open
.creator
- Created by #{link_to_member(@project, @issue.author)} #{time_ago_with_tooltip(@issue.created_at)}
+ Created by #{link_to_member(@project, @issue.author)} #{issue_timestamp(@issue)}
%h4.title
= gfm escape_once(@issue.title)
diff --git a/app/views/projects/merge_requests/show/_how_to_merge.html.haml b/app/views/projects/merge_requests/show/_how_to_merge.html.haml
index 9540453ce3e..63db4b30968 100644
--- a/app/views/projects/merge_requests/show/_how_to_merge.html.haml
+++ b/app/views/projects/merge_requests/show/_how_to_merge.html.haml
@@ -10,11 +10,11 @@
- target_remote = @merge_request.target_project.namespace.nil? ? "target" :@merge_request.target_project.namespace.path
%p
%strong Step 1.
- Checkout the branch we are going to merge and pull in the code
+ Fetch the code and create a new branch pointing to it
%pre.dark
:preserve
- git checkout -b #{@merge_request.source_project_path}-#{@merge_request.source_branch} #{@merge_request.target_branch}
- git pull #{@merge_request.source_project.http_url_to_repo} #{@merge_request.source_branch}
+ git fetch #{@merge_request.source_project.http_url_to_repo} #{@merge_request.source_branch}
+ git checkout -b #{@merge_request.source_project_path}-#{@merge_request.source_branch} FETCH_HEAD
%p
%strong Step 2.
Merge the branch and push the changes to GitLab
diff --git a/app/views/projects/new_tree/show.html.haml b/app/views/projects/new_tree/show.html.haml
index c47c0a3f642..f09d3659774 100644
--- a/app/views/projects/new_tree/show.html.haml
+++ b/app/views/projects/new_tree/show.html.haml
@@ -19,14 +19,14 @@
Encoding
.col-sm-10
= select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'form-control'
- = render 'shared/commit_message_container', params: params,
- placeholder: 'Add new file'
.file-holder
.file-title
%i.fa.fa-file
.file-content.code
%pre#editor= params[:content]
+ = render 'shared/commit_message_container', params: params,
+ placeholder: 'Add new file'
= hidden_field_tag 'content', '', id: 'file-content'
= render 'projects/commit_button', ref: @ref,
cancel_path: project_tree_path(@project, @id)
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index 814bf19970c..a25c5e207fb 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -59,7 +59,7 @@
- if note.attachment.image?
= link_to note.attachment.secure_url, target: '_blank' do
= image_tag note.attachment.secure_url, class: 'note-image-attach'
- .attachment.pull-right
+ .attachment
= link_to note.attachment.secure_url, target: "_blank" do
%i.fa.fa-paperclip
= note.attachment_identifier
diff --git a/app/views/projects/team_members/_team_member.html.haml b/app/views/projects/team_members/_team_member.html.haml
index 5f29b58de32..7a9c0939ba0 100644
--- a/app/views/projects/team_members/_team_member.html.haml
+++ b/app/views/projects/team_members/_team_member.html.haml
@@ -5,7 +5,7 @@
- unless @project.personal? && user == current_user
.pull-left
= form_for(member, as: :project_member, url: project_team_member_path(@project, member.user)) do |f|
- = f.select :access_level, options_for_select(ProjectMember.access_roles, member.access_level), {}, class: "medium project-access-select span2 trigger-submit"
+ = f.select :access_level, options_for_select(ProjectMember.access_roles, member.access_level), {}, class: "trigger-submit"
&nbsp;
= link_to project_team_member_path(@project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from team' do
%i.fa.fa-minus.fa-inverse
diff --git a/db/fixtures/production/001_admin.rb b/db/fixtures/production/001_admin.rb
index e0b13db020d..0755ac714e1 100644
--- a/db/fixtures/production/001_admin.rb
+++ b/db/fixtures/production/001_admin.rb
@@ -1,8 +1,10 @@
-password = if ENV['GITLAB_ROOT_PASSWORD'].blank?
- "5iveL!fe"
- else
- ENV['GITLAB_ROOT_PASSWORD']
- end
+if ENV['GITLAB_ROOT_PASSWORD'].blank?
+ password = '5iveL!fe'
+ expire_time = Time.now
+else
+ password = ENV['GITLAB_ROOT_PASSWORD']
+ expire_time = nil
+end
admin = User.create(
email: "admin@example.com",
@@ -10,7 +12,7 @@ admin = User.create(
username: 'root',
password: password,
password_confirmation: password,
- password_expires_at: Time.now,
+ password_expires_at: expire_time,
theme_id: Gitlab::Theme::MARS
)
diff --git a/doc/README.md b/doc/README.md
index 7343d5ae273..b9aa12f7675 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -16,6 +16,7 @@
- [Install](install/README.md) Requirements, directory structures and manual installation.
- [Integration](integration/README.md) How to integrate with systems such as JIRA, Redmine, LDAP and Twitter.
- [Raketasks](raketasks/README.md) Explore what GitLab has in store for you to make administration easier.
+- [Custom git hooks](hooks/custom_hooks.md) Custom git hooks (on the filesystem) for when web hooks aren't enough.
- [System hooks](system_hooks/system_hooks.md) Let GitLab notify you when certain management tasks need to be carried out.
- [Security](security/README.md) Learn what you can do to further secure your GitLab instance.
- [Update](update/README.md) Update guides to upgrade your installation.
diff --git a/doc/api/commits.md b/doc/api/commits.md
index 9475ecbaa67..eb8d6a43592 100644
--- a/doc/api/commits.md
+++ b/doc/api/commits.md
@@ -93,3 +93,66 @@ Parameters:
}
]
```
+
+## Get the comments of a commit
+
+Get the comments of a commit in a project.
+
+```
+GET /projects/:id/repository/commits/:sha/comments
+```
+
+Parameters:
+
+- `id` (required) - The ID of a project
+- `sha` (required) - The name of a repository branch or tag or if not given the default branch
+
+```json
+[
+ {
+ "note": "this code is really nice",
+ "author": {
+ "id": 11,
+ "username": "admin",
+ "email": "admin@local.host",
+ "name": "Administrator",
+ "state": "active",
+ "created_at": "2014-03-06T08:17:35.000Z"
+ }
+ }
+]
+```
+
+## Post comment to commit
+
+Adds a comment to a commit. Optionally you can post comments on a specific line of a commit. Therefor both `path`, `line_new` and `line_old` are required.
+
+```
+POST /projects/:id/repository/commits/:sha/comments
+```
+
+Parameters:
+
+- `id` (required) - The ID of a project
+- `sha` (required) - The name of a repository branch or tag or if not given the default branch
+- `note` (required) - Text of comment
+- `path` (optional) - The file path
+- `line` (optional) - The line number
+- `line_type` (optional) - The line type (new or old)
+
+```json
+{
+ "author": {
+ "id": 1,
+ "username": "admin",
+ "email": "admin@local.host",
+ "name": "Administrator",
+ "blocked": false,
+ "created_at": "2012-04-29T08:46:00Z"
+ },
+ "note": "text1",
+ "path": "example.rb",
+ "line": 5,
+ "line_type": "new"
+}
+```
diff --git a/doc/hooks/custom_hooks.md b/doc/hooks/custom_hooks.md
new file mode 100644
index 00000000000..00867ead80d
--- /dev/null
+++ b/doc/hooks/custom_hooks.md
@@ -0,0 +1,41 @@
+# Custom Git Hooks
+
+**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 as an option if you do not have filesystem access.**
+
+Git natively supports hooks that are executed on different actions.
+Examples of server-side git hooks include pre-receive, post-receive, and update.
+See
+[Git SCM Server-Side Hooks](http://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#Server-Side-Hooks)
+for more information about each hook type.
+
+As of gitlab-shell version 2.2.0 (which requires GitLab 7.5+), GitLab
+administrators can add custom git hooks to any GitLab project.
+
+## Setup
+
+Normally, git hooks are placed in the repository or project's `hooks` directory.
+GitLab creates a symlink from each project's `hooks` directory to the
+gitlab-shell `hooks` directory for ease of maintenance between gitlab-shell
+upgrades. As such, custom hooks are implemented a little differently. Behavior
+is exactly the same once the hook is created, though. Follow these steps to
+set up a custom hook.
+
+1. Pick a project that needs a custom git hook.
+1. On the GitLab server, navigate to the project's repository directory.
+For a manual install the path is usually
+`/home/git/repositories/<group>/<project>.git`. For Omnibus installs the path is
+usually `/var/opt/gitlab/git-data/repositories/<group>/<project>.git`.
+1. Create a new directory in this location called `custom_hooks`.
+1. Inside the new `custom_hooks` directory, create a file with a name matching
+the hook type. For a pre-receive hook the file name should be `pre-receive` with
+no extension.
+1. Make the hook file executable and make sure it's owned by git.
+1. Write the code to make the git hook function as expected. Hooks can be
+in any language. Ensure the 'shebang' at the top properly reflects the language
+type. For example, if the script is in Ruby the shebang will probably be
+`#!/usr/bin/env ruby`.
+
+That's it! Assuming the hook code is properly implemented the hook will fire
+as appropriate.
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index ed194253148..fd59ac8a073 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -50,11 +50,6 @@ We love [JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/) but GitLab
### Memory
-- 512MB is the absolute minimum but we do not recommend this amount of memory.
-You will either need to configure 512MB or 1.5GB of swap space.
-With 512MB of swap space you must configure only one unicorn worker.
-With one unicorn worker only git over ssh access will work because the git over HTTP access requires two running workers (one worker to receive the user request and one worker for the authorization check).
-If you use SSD storage and configure 1.5GB of swap space you can use two Unicorn workers, this will allow HTTP access but it will still be slow.
- 1GB RAM + 1GB swap supports up to 100 users
- **2GB RAM** is the **recommended** memory size and supports up to 500 users
- 4GB RAM supports up to 2,000 users
@@ -90,7 +85,7 @@ On a very active server (10,000 active users) the Sidekiq process can use 1GB+ o
## Supported web browsers
- Chrome (Latest stable version)
-- Firefox (Latest released version and [latest ESR version](https://www.mozilla.org/en-US/firefox/organizations/))
+- Firefox (Latest released version and [latest ESR version](https://www.mozilla.org/en-US/firefox/organizations/))
- Safari 7+ (known problem: required fields in html5 do not work)
- Opera (Latest released version)
- IE 10+
diff --git a/doc/integration/gitlab_actions.png b/doc/integration/gitlab_actions.png
new file mode 100644
index 00000000000..b08f54d137b
--- /dev/null
+++ b/doc/integration/gitlab_actions.png
Binary files differ
diff --git a/doc/integration/gitlab_buttons_in_gmail.md b/doc/integration/gitlab_buttons_in_gmail.md
new file mode 100644
index 00000000000..5cfea5a90f8
--- /dev/null
+++ b/doc/integration/gitlab_buttons_in_gmail.md
@@ -0,0 +1,11 @@
+# GitLab buttons in gmail
+
+GitLab supports [Google actions in email](https://developers.google.com/gmail/markup/actions/actions-overview).
+
+If correctly setup, emails that require an action will be marked in Gmail.
+
+![gitlab_actions](gitlab_actions.png)
+
+To get this functioning, you need to be registered with Google.
+[See how to register with google in this document.](https://developers.google.com/gmail/markup/registering-with-google)
+
diff --git a/doc/release/monthly.md b/doc/release/monthly.md
index e0c98fbce76..c50bfc21f8f 100644
--- a/doc/release/monthly.md
+++ b/doc/release/monthly.md
@@ -143,35 +143,28 @@ Make sure the code quality indicators are green / good.
- [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq)
-### **4. Set VERSION**
+### **4. Run release tool**
-Change version in VERSION to `x.x.0.rc1`.
+**Make sure EE `master` has latest changes from CE `master`**
-### **5. Tag**
-
-Create an annotated tag that points to the version change commit:
+Get release tools
```
-git tag -a vx.x.0.rc1 -m 'Version x.x.0.rc1'
+git clone git@dev.gitlab.org:gitlab/release-tools.git
+cd release-tools
```
-Tags should be created for both GitLab CE and GitLab EE. Don't forget to push tags to all remotes.
+Release candidate creates stable branch from master.
+So we need to sync master branch between all CE remotes. Also do same for EE.
```
-git push remote_name vx.x.0.rc1
+bundle exec rake sync
```
-### **6. Create stable branches**
-
-For GitLab EE, append `-ee` to the branch.
-
-`x-x-stable-ee`
+Create release candidate and stable branch:
```
-git checkout master
-git pull
-git checkout -b x-x-stable
-git push <remote> x-x-stable
+bundle exec rake release["x.x.0.rc1"]
```
Now developers can use master for merging new features.
@@ -245,69 +238,45 @@ create an issue about it in order to discuss the next steps after the release.
# **22nd - Release CE and EE**
-For GitLab EE, append `-ee` to the branches and tags.
+**Make sure EE `x-x-stable-ee` has latest changes from CE `x-x-stable`**
-`x-x-stable-ee`
-`v.x.x.0-ee`
+### **1. Release code**
-Note: Merge CE into EE if needed.
-
-### **1. Set VERSION to x.x.x and push**
-
-- Change the GITLAB_SHELL_VERSION file in `master` of the CE repository if the version changed.
-- Change the GITLAB_SHELL_VERSION file in `master` of the EE repository if the version changed.
-- Change the VERSION file in `master` branch of the CE repository and commit and push to origin.
-- Change the VERSION file in `master` branch of the EE repository and commit and push to origin.
-
-### **2. Update installation.md**
-
-Update [installation.md](/doc/install/installation.md) to the newest version in master.
-
-### **3. Push latest changes from x-x-stable branch to dev.gitlab.org**
+Get release tools
```
-git checkout -b x-x-stable
-git push origin x-x-stable
+git clone git@dev.gitlab.org:gitlab/release-tools.git
+cd release-tools
```
-### **4. Build the Omnibus packages**
-
-Follow the [release doc in the Omnibus repository](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/release.md).
-This can happen before tagging because Omnibus uses tags in its own repo and SHA1's to refer to the GitLab codebase.
-
-### **5. Create annotated tag vx.x.x**
-
-In `x-x-stable` branch check for the SHA-1 of the commit with VERSION file changed. Tag that commit,
+Bump version, create release tag and push to remotes:
```
-git tag -a vx.x.0 -m 'Version x.x.0' xxxxx
+bundle exec rake release["x.x.0"]
```
-where `xxxxx` is SHA-1.
-### **6. Push the tag and x-x-stable branch to the remotes**
+### **2. Update installation.md**
-For GitLab CE, push to dev, GitLab.com and GitHub.
+Update [installation.md](/doc/install/installation.md) to the newest version in master.
-For GitLab EE, push to the subscribers repo.
-Make sure the branch is marked 'protected' on each of the remotes you pushed to.
+### **3. Build the Omnibus packages**
+
+Follow the [release doc in the Omnibus repository](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/release.md).
+This can happen before tagging because Omnibus uses tags in its own repo and SHA1's to refer to the GitLab codebase.
-```
-git push <remote> x-x-stable(-ee)
-git push <remote> vx.x.0
-```
-### **7. Publish packages for new release**
+### **4. Publish packages for new release**
Update `downloads/index.html` and `downloads/archive/index.html` in `www-gitlab-com` repository.
-### **8. Publish blog for new release**
+### **5. Publish blog for new release**
Merge the [blog merge request](#1-prepare-the-blog-post) in `www-gitlab-com` repository.
-### **9. Tweet to blog**
+### **6. Tweet to blog**
Send out a tweet to share the good news with the world.
List the most important features and link to the blog post.
diff --git a/doc/release/patch.md b/doc/release/patch.md
index 5d2fa053cac..6ed56427e9a 100644
--- a/doc/release/patch.md
+++ b/doc/release/patch.md
@@ -10,6 +10,8 @@ Otherwise include it in the monthly release and note there was a regression fix
## Release Procedure
+### Preparation
+
1. Verify that the issue can be reproduced
1. Note in the 'GitLab X.X regressions' that you will create a patch
1. Create an issue on private GitLab development server
@@ -17,12 +19,33 @@ Otherwise include it in the monthly release and note there was a regression fix
1. Fix the issue on a feature branch, do this on the private GitLab development server
1. Consider creating and testing workarounds
1. After the branch is merged into master, cherry pick the commit(s) into the current stable branch
+1. Make sure that the build has passed and all tests are passing
1. In a separate commit in the stable branch update the CHANGELOG
1. For EE, update the CHANGELOG-EE if it is EE specific fix. Otherwise, merge the stable CE branch and add to CHANGELOG-EE "Merge community edition changes for version X.X.X"
-1. In a separate commit in the stable branch update the VERSION
-1. Create an annotated tag vX.X.X for CE and another patch release for EE `git tag -a vx.x.x -m 'Version x.x.x'`
-1. Make sure that the build has passed and all tests are passing
-1. Push the code and the tags to all the CE and EE repositories
+
+### Bump version
+
+Get release tools
+
+```
+git clone git@dev.gitlab.org:gitlab/release-tools.git
+cd release-tools
+```
+
+Bump version in stable branch, create release tag and push to remotes:
+
+```
+bundle exec rake release["x.x.x"]
+```
+
+Or if you need to release only EE:
+
+```
+CE=false be rake release['x.x.x']
+```
+
+### Release
+
1. Apply the patch to GitLab Cloud and the private GitLab development server
1. [Build new packages with the latest version](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/release.md)
1. Cherry-pick the changelog update back into master
diff --git a/doc/update/upgrader.md b/doc/update/upgrader.md
index cf59b0e461c..44e18a9ed42 100644
--- a/doc/update/upgrader.md
+++ b/doc/update/upgrader.md
@@ -43,28 +43,31 @@ Check if GitLab and its dependencies are configured correctly:
If all items are green, then congratulations upgrade is complete!
-## 5. Upgrade GitLab Shell (if needed)
+## 5. Upgrade GitLab Shell
-If the `gitlab:check` task reports an outdated version of `gitlab-shell` you should upgrade it.
-
-Upgrade it by running the commands below after replacing 2.0.1 with the correct version number:
+GitLab Shell might be outdated, running the commands below ensures you're using a compatible version:
```
cd /home/git/gitlab-shell
sudo -u git -H git fetch
-sudo -u git -H git checkout v2.0.1
+sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_SHELL_VERSION`
```
## One line upgrade command
You've read through the entire guide and probably already did all the steps one by one.
-Here is a one line command with step 1 to 4 for the next time you upgrade:
+Here is a one line command with step 1 to 5 for the next time you upgrade:
```bash
-cd /home/git/gitlab; sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production; \
+cd /home/git/gitlab; \
+ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production; \
sudo service gitlab stop; \
if [ -f bin/upgrade.rb ]; then sudo -u git -H ruby bin/upgrade.rb -y; else sudo -u git -H ruby script/upgrade.rb -y; fi; \
+ cd /home/git/gitlab-shell; \
+ sudo -u git -H git fetch; \
+ sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_SHELL_VERSION`; \
+ cd /home/git/gitlab; \
sudo service gitlab start; \
sudo service nginx restart; sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
```
diff --git a/lib/api/commits.rb b/lib/api/commits.rb
index 4a67313430a..6c5391b98c8 100644
--- a/lib/api/commits.rb
+++ b/lib/api/commits.rb
@@ -50,6 +50,67 @@ module API
not_found! "Commit" unless commit
commit.diffs
end
+
+ # Get a commit's comments
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # sha (required) - The commit hash
+ # Examples:
+ # GET /projects/:id/repository/commits/:sha/comments
+ get ':id/repository/commits/:sha/comments' do
+ sha = params[:sha]
+ commit = user_project.repository.commit(sha)
+ not_found! 'Commit' unless commit
+ notes = Note.where(commit_id: commit.id)
+ present paginate(notes), with: Entities::CommitNote
+ end
+
+ # Post comment to commit
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # sha (required) - The commit hash
+ # note (required) - Text of comment
+ # path (optional) - The file path
+ # line (optional) - The line number
+ # line_type (optional) - The type of line (new or old)
+ # Examples:
+ # POST /projects/:id/repository/commits/:sha/comments
+ post ':id/repository/commits/:sha/comments' do
+ required_attributes! [:note]
+
+ sha = params[:sha]
+ commit = user_project.repository.commit(sha)
+ not_found! 'Commit' unless commit
+ opts = {
+ note: params[:note],
+ noteable_type: 'Commit',
+ commit_id: commit.id
+ }
+
+ if params[:path] && params[:line] && params[:line_type]
+ commit.diffs.each do |diff|
+ next unless diff.new_path == params[:path]
+ lines = Gitlab::Diff::Parser.new.parse(diff.diff.lines.to_a)
+
+ lines.each do |line|
+ next unless line.new_pos == params[:line].to_i && line.type == params[:line_type]
+ break opts[:line_code] = Gitlab::Diff::LineCode.generate(diff.new_path, line.new_pos, line.old_pos)
+ end
+
+ break if opts[:line_code]
+ end
+ end
+
+ note = ::Notes::CreateService.new(user_project, current_user, opts).execute
+
+ if note.save
+ present note, with: Entities::CommitNote
+ else
+ not_found!
+ end
+ end
end
end
end
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 40696489ba2..42e4442365d 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -179,6 +179,14 @@ module API
expose :author, using: Entities::UserBasic
end
+ class CommitNote < Grape::Entity
+ expose :note
+ expose(:path) { |note| note.diff_file_name }
+ expose(:line) { |note| note.diff_new_line }
+ expose(:line_type) { |note| note.diff_line_type }
+ expose :author, using: Entities::UserBasic
+ end
+
class Event < Grape::Entity
expose :title, :project_id, :action_name
expose :target_id, :target_type, :author_id
diff --git a/lib/backup/database.rb b/lib/backup/database.rb
index d12d30a9110..ea659e3b605 100644
--- a/lib/backup/database.rb
+++ b/lib/backup/database.rb
@@ -34,6 +34,7 @@ module Backup
# Drop all tables because PostgreSQL DB dumps do not contain DROP TABLE
# statements like MySQL.
Rake::Task["gitlab:db:drop_all_tables"].invoke
+ Rake::Task["gitlab:db:drop_all_postgres_sequences"].invoke
pg_env
system('psql', config['database'], '-f', db_file_name)
end
diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb
index 380beac708d..faa1b3b4099 100644
--- a/lib/backup/repository.rb
+++ b/lib/backup/repository.rb
@@ -59,7 +59,13 @@ module Backup
project.namespace.ensure_dir_exist if project.namespace
- if system(*%W(git clone --bare #{path_to_bundle(project)} #{path_to_repo(project)}), silent)
+ if File.exists?(path_to_bundle(project))
+ cmd = %W(git clone --bare #{path_to_bundle(project)} #{path_to_repo(project)})
+ else
+ cmd = %W(git init --bare #{path_to_repo(project)})
+ end
+
+ if system(*cmd, silent)
puts "[DONE]".green
else
puts "[FAILED]".red
@@ -91,7 +97,7 @@ module Backup
protected
def path_to_repo(project)
- File.join(repos_path, project.path_with_namespace + '.git')
+ project.repository.path_to_repo
end
def path_to_bundle(project)
diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb
index cc320da751c..aabc7f1e69a 100644
--- a/lib/gitlab/backend/shell.rb
+++ b/lib/gitlab/backend/shell.rb
@@ -8,6 +8,13 @@ module Gitlab
end
end
+ class << self
+ def version_required
+ @version_required ||= File.read(Rails.root.
+ join('GITLAB_SHELL_VERSION')).strip
+ end
+ end
+
# Init new repository
#
# name - project path with namespace
diff --git a/lib/gitlab/git_ref_validator.rb b/lib/gitlab/git_ref_validator.rb
index 0fdd4dbe577..39d17def930 100644
--- a/lib/gitlab/git_ref_validator.rb
+++ b/lib/gitlab/git_ref_validator.rb
@@ -6,7 +6,7 @@ module Gitlab
# Returns true for a valid reference name, false otherwise
def validate(ref_name)
Gitlab::Utils.system_silent(
- %W(git check-ref-format refs/#{ref_name})) == 0
+ %W(git check-ref-format refs/#{ref_name}))
end
end
end
diff --git a/lib/gitlab/utils.rb b/lib/gitlab/utils.rb
index bc30364550a..bd184c27187 100644
--- a/lib/gitlab/utils.rb
+++ b/lib/gitlab/utils.rb
@@ -5,10 +5,9 @@ module Gitlab
# Run system command without outputting to stdout.
#
# @param cmd [Array<String>]
- # @return [Integer] exit status
+ # @return [Boolean]
def system_silent(cmd)
- IO.popen(cmd).close
- $?.exitstatus
+ Popen::popen(cmd).last.zero?
end
end
end
diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab
index 49a68c62293..c8b769ace8e 100644
--- a/lib/support/nginx/gitlab
+++ b/lib/support/nginx/gitlab
@@ -1,5 +1,5 @@
## GitLab
-## Maintainer: @randx
+## Contributors: randx, yin8086, sashkab, orkoden, axilleas, bbodenmiller
##
## Lines starting with two hashes (##) are comments with information.
## Lines starting with one hash (#) are configuration parameters that can be uncommented.
@@ -15,7 +15,7 @@
## - installing an old version of Nginx with the chunkin module [2] compiled in, or
## - using a newer version of Nginx.
##
-## At the time of writing we do not know if either of these theoretical solutions works.
+## At the time of writing we do not know if either of these theoretical solutions works.
## As a workaround users can use Git over SSH to push large files.
##
## [0] https://git.kernel.org/cgit/git/git.git/tree/Documentation/technical/http-protocol.txt#n99
@@ -26,6 +26,7 @@
## configuration ##
###################################
##
+## See installation.md#using-https for additional HTTPS configuration details.
upstream gitlab {
server unix:/home/git/gitlab/tmp/sockets/gitlab.socket fail_timeout=0;
@@ -33,7 +34,8 @@ upstream gitlab {
## Normal HTTP host
server {
- listen *:80 default_server;
+ listen 0.0.0.0:80 default_server;
+ listen [::]:80 default_server;
server_name YOUR_SERVER_FQDN; ## Replace this with something like gitlab.example.com
server_tokens off; ## Don't show the nginx version number, a security best practice
root /home/git/gitlab/public;
@@ -42,6 +44,8 @@ server {
## Or if you want to accept large git objects over http
client_max_body_size 20m;
+ ## See app/controllers/application_controller.rb for headers set
+
## Individual nginx logs for this GitLab vhost
access_log /var/log/nginx/gitlab_access.log;
error_log /var/log/nginx/gitlab_error.log;
diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl
index cbb198086b5..4e53d5e8b50 100644
--- a/lib/support/nginx/gitlab-ssl
+++ b/lib/support/nginx/gitlab-ssl
@@ -1,5 +1,5 @@
## GitLab
-## Contributors: randx, yin8086, sashkab, orkoden, axilleas
+## Contributors: randx, yin8086, sashkab, orkoden, axilleas, bbodenmiller
##
## Modified from nginx http version
## Modified from http://blog.phusion.nl/2012/04/21/tutorial-setting-up-gitlab-on-debian-6/
@@ -26,9 +26,8 @@
## [1] https://github.com/agentzh/chunkin-nginx-module#status
## [2] https://github.com/agentzh/chunkin-nginx-module
##
-##
###################################
-## SSL configuration ##
+## configuration ##
###################################
##
## See installation.md#using-https for additional HTTPS configuration details.
@@ -37,22 +36,24 @@ upstream gitlab {
server unix:/home/git/gitlab/tmp/sockets/gitlab.socket fail_timeout=0;
}
-## Normal HTTP host
+## Redirects all HTTP traffic to the HTTPS host
server {
- listen *:80 default_server;
+ listen 0.0.0.0:80;
+ listen [::]:80 default_server;
server_name YOUR_SERVER_FQDN; ## Replace this with something like gitlab.example.com
server_tokens off; ## Don't show the nginx version number, a security best practice
-
- ## Redirects all traffic to the HTTPS host
- root /nowhere; ## root doesn't have to be a valid path since we are redirecting
- rewrite ^ https://$server_name$request_uri? permanent;
+ return 301 https://$server_name$request_uri;
+ access_log /var/log/nginx/gitlab_access.log;
+ error_log /var/log/nginx/gitlab_error.log;
}
+
## HTTPS host
server {
- listen 443 ssl;
+ listen 0.0.0.0:443 ssl;
+ listen [::]:443 ssl default_server;
server_name YOUR_SERVER_FQDN; ## Replace this with something like gitlab.example.com
- server_tokens off;
+ server_tokens off; ## Don't show the nginx version number, a security best practice
root /home/git/gitlab/public;
## Increase this if you want to upload large attachments
@@ -70,12 +71,9 @@ server {
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
+ ssl_session_timeout 5m;
- ## [WARNING] The following header states that the browser should only communicate
- ## with your server over a secure connection for the next 24 months.
- add_header Strict-Transport-Security max-age=63072000;
- add_header X-Frame-Options SAMEORIGIN;
- add_header X-Content-Type-Options nosniff;
+ ## See app/controllers/application_controller.rb for headers set
## [Optional] If your certficate has OCSP, enable OCSP stapling to reduce the overhead and latency of running SSL.
## Replace with your ssl_trusted_certificate. For more info see:
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index 56e8ff44988..7ff23a7600a 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -574,20 +574,16 @@ namespace :gitlab do
Gitlab::Shell.new.version
end
- def required_gitlab_shell_version
- File.read(File.join(Rails.root, "GITLAB_SHELL_VERSION")).strip
- end
-
def gitlab_shell_major_version
- required_gitlab_shell_version.split(".")[0].to_i
+ Gitlab::Shell.version_required.split('.')[0].to_i
end
def gitlab_shell_minor_version
- required_gitlab_shell_version.split(".")[1].to_i
+ Gitlab::Shell.version_required.split('.')[1].to_i
end
def gitlab_shell_patch_version
- required_gitlab_shell_version.split(".")[2].to_i
+ Gitlab::Shell.version_required.split('.')[2].to_i
end
def has_gitlab_shell3?
diff --git a/lib/tasks/gitlab/cleanup.rake b/lib/tasks/gitlab/cleanup.rake
index 63dcdc52370..189ad6090a4 100644
--- a/lib/tasks/gitlab/cleanup.rake
+++ b/lib/tasks/gitlab/cleanup.rake
@@ -92,11 +92,11 @@ namespace :gitlab do
User.ldap.each do |ldap_user|
print "#{ldap_user.name} (#{ldap_user.extern_uid}) ..."
- if Gitlab::LDAP::Access.open { |access| access.allowed?(ldap_user) }
+ if Gitlab::LDAP::Access.allowed?(ldap_user)
puts " [OK]".green
else
if block_flag
- ldap_user.block!
+ ldap_user.block! unless ldap_user.blocked?
puts " [BLOCKED]".red
else
puts " [NOT IN LDAP]".yellow
diff --git a/lib/tasks/gitlab/db/drop_all_postgres_sequences.rake b/lib/tasks/gitlab/db/drop_all_postgres_sequences.rake
new file mode 100644
index 00000000000..e9cf0a9b5e8
--- /dev/null
+++ b/lib/tasks/gitlab/db/drop_all_postgres_sequences.rake
@@ -0,0 +1,10 @@
+namespace :gitlab do
+ namespace :db do
+ task drop_all_postgres_sequences: :environment do
+ connection = ActiveRecord::Base.connection
+ connection.execute("SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';").each do |sequence|
+ connection.execute("DROP SEQUENCE #{sequence['relname']}")
+ end
+ end
+ end
+end
diff --git a/lib/tasks/gitlab/shell.rake b/lib/tasks/gitlab/shell.rake
index 55f338add6a..202e55c89ad 100644
--- a/lib/tasks/gitlab/shell.rake
+++ b/lib/tasks/gitlab/shell.rake
@@ -4,7 +4,7 @@ namespace :gitlab do
task :install, [:tag, :repo] => :environment do |t, args|
warn_user_is_not_gitlab
- default_version = File.read(File.join(Rails.root, "GITLAB_SHELL_VERSION")).strip
+ default_version = Gitlab::Shell.version_required
args.with_defaults(tag: 'v' + default_version, repo: "https://gitlab.com/gitlab-org/gitlab-shell.git")
user = Gitlab.config.gitlab.user
@@ -76,7 +76,7 @@ namespace :gitlab do
desc "GITLAB | Build missing projects"
task build_missing_projects: :environment do
Project.find_each(batch_size: 1000) do |project|
- path_to_repo = File.join(Gitlab.config.gitlab_shell.repos_path, "#{project.path_with_namespace}.git")
+ path_to_repo = project.repository.path_to_repo
if File.exists?(path_to_repo)
print '-'
else
diff --git a/spec/controllers/branches_controller_spec.rb b/spec/controllers/branches_controller_spec.rb
new file mode 100644
index 00000000000..610d7a84e31
--- /dev/null
+++ b/spec/controllers/branches_controller_spec.rb
@@ -0,0 +1,51 @@
+require 'spec_helper'
+
+describe Projects::BranchesController do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+
+ project.team << [user, :master]
+
+ project.stub(:branches).and_return(['master', 'foo/bar/baz'])
+ project.stub(:tags).and_return(['v1.0.0', 'v2.0.0'])
+ controller.instance_variable_set(:@project, project)
+ end
+
+ describe "POST create" do
+ render_views
+
+ before {
+ post :create,
+ project_id: project.to_param,
+ branch_name: branch,
+ ref: ref
+ }
+
+ context "valid branch name, valid source" do
+ let(:branch) { "merge_branch" }
+ let(:ref) { "master" }
+ it { should redirect_to("/#{project.path_with_namespace}/tree/merge_branch") }
+ end
+
+ context "invalid branch name, valid ref" do
+ let(:branch) { "<script>alert('merge');</script>" }
+ let(:ref) { "master" }
+ it { should redirect_to("/#{project.path_with_namespace}/tree/alert('merge');") }
+ end
+
+ context "valid branch name, invalid ref" do
+ let(:branch) { "merge_branch" }
+ let(:ref) { "<script>alert('ref');</script>" }
+ it { should render_template("new") }
+ end
+
+ context "invalid branch name, invalid ref" do
+ let(:branch) { "<script>alert('merge');</script>" }
+ let(:ref) { "<script>alert('ref');</script>" }
+ it { should render_template("new") }
+ end
+ end
+end
diff --git a/spec/models/gitlab_ci_service_spec.rb b/spec/models/gitlab_ci_service_spec.rb
index ebc377047be..83277058fbb 100644
--- a/spec/models/gitlab_ci_service_spec.rb
+++ b/spec/models/gitlab_ci_service_spec.rb
@@ -34,11 +34,11 @@ describe GitlabCiService do
end
describe :commit_status_path do
- it { @service.commit_status_path("2ab7834c").should == "http://ci.gitlab.org/projects/2/builds/2ab7834c/status.json?token=verySecret"}
+ it { @service.commit_status_path("2ab7834c").should == "http://ci.gitlab.org/projects/2/commits/2ab7834c/status.json?token=verySecret"}
end
describe :build_page do
- it { @service.build_page("2ab7834c").should == "http://ci.gitlab.org/projects/2/builds/2ab7834c"}
+ it { @service.build_page("2ab7834c").should == "http://ci.gitlab.org/projects/2/commits/2ab7834c"}
end
end
end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 2d839e9611b..6ab7162c15c 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -249,6 +249,12 @@ describe Note do
its(:note) { should == "_mentioned in merge request !#{mergereq.iid}_" }
end
+ context 'commit contained in a merge request' do
+ subject { Note.create_cross_reference_note(mergereq.commits.first, mergereq, author, project) }
+
+ it { should be_nil }
+ end
+
context 'commit from issue' do
subject { Note.create_cross_reference_note(commit, issue, author, project) }
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 48b58400a1e..70a15cac1a8 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -145,63 +145,6 @@ describe Project do
end
end
- describe 'comment merge requests with commits' do
- before do
- @user = create(:user)
- group = create(:group)
- group.add_owner(@user)
-
- @project = create(:project, namespace: group)
- @fork_project = Projects::ForkService.new(@project, @user).execute
- @merge_request = create(:merge_request, source_project: @project,
- source_branch: 'master',
- target_branch: 'feature',
- target_project: @project)
- @fork_merge_request = create(:merge_request, source_project: @fork_project,
- source_branch: 'master',
- target_branch: 'feature',
- target_project: @project)
-
- @commits = @merge_request.commits
- end
-
- context 'push to origin repo source branch' do
- before do
- @project.comment_mr_with_commits('master', @commits, @user)
- end
-
- it { @merge_request.notes.should_not be_empty }
- it { @fork_merge_request.notes.should be_empty }
- end
-
- context 'push to origin repo target branch' do
- before do
- @project.comment_mr_with_commits('feature', @commits, @user)
- end
-
- it { @merge_request.notes.should be_empty }
- it { @fork_merge_request.notes.should be_empty }
- end
-
- context 'push to fork repo source branch' do
- before do
- @fork_project.comment_mr_with_commits('master', @commits, @user)
- end
-
- it { @merge_request.notes.should be_empty }
- it { @fork_merge_request.notes.should_not be_empty }
- end
-
- context 'push to fork repo target branch' do
- before do
- @fork_project.comment_mr_with_commits('feature', @commits, @user)
- end
-
- it { @merge_request.notes.should be_empty }
- it { @fork_merge_request.notes.should be_empty }
- end
- end
-
describe :find_with_namespace do
context 'with namespace' do
before do
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index 38e0a284c36..a3f58f50913 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -8,6 +8,7 @@ describe API::API, api: true do
let!(:project) { create(:project, creator_id: user.id) }
let!(:master) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) }
let!(:guest) { create(:project_member, user: user2, project: project, access_level: ProjectMember::GUEST) }
+ let!(:note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'a comment on a commit') }
before { project.team << [user, :reporter] }
@@ -81,4 +82,68 @@ describe API::API, api: true do
end
end
end
+
+ describe 'GET /projects:id/repository/commits/:sha/comments' do
+ context 'authorized user' do
+ it 'should return merge_request comments' do
+ get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user)
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.length.should == 1
+ json_response.first['note'].should == 'a comment on a commit'
+ json_response.first['author']['id'].should == user.id
+ end
+
+ it 'should return a 404 error if merge_request_id not found' do
+ get api("/projects/#{project.id}/repository/commits/1234ab/comments", user)
+ response.status.should == 404
+ end
+ end
+
+ context 'unauthorized user' do
+ it 'should not return the diff of the selected commit' do
+ get api("/projects/#{project.id}/repository/commits/1234ab/comments")
+ response.status.should == 401
+ end
+ end
+ end
+
+ describe 'POST /projects:id/repository/commits/:sha/comments' do
+ context 'authorized user' do
+ it 'should return comment' do
+ post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment'
+ response.status.should == 201
+ json_response['note'].should == 'My comment'
+ json_response['path'].should be_nil
+ json_response['line'].should be_nil
+ json_response['line_type'].should be_nil
+ end
+
+ it 'should return the inline comment' do
+ post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment', path: project.repository.commit.diffs.first.new_path, line: 7, line_type: 'new'
+ response.status.should == 201
+ json_response['note'].should == 'My comment'
+ json_response['path'].should == project.repository.commit.diffs.first.new_path
+ json_response['line'].should == 7
+ json_response['line_type'].should == 'new'
+ end
+
+ it 'should return 400 if note is missing' do
+ post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user)
+ response.status.should == 400
+ end
+
+ it 'should return 404 if note is attached to non existent commit' do
+ post api("/projects/#{project.id}/repository/commits/1234ab/comments", user), note: 'My comment'
+ response.status.should == 404
+ end
+ end
+
+ context 'unauthorized user' do
+ it 'should not return the diff of the selected commit' do
+ post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments")
+ response.status.should == 401
+ end
+ end
+ end
end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 067935c82a6..2c4b68c10b6 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -203,14 +203,12 @@ describe API::API, api: true do
json_response['message']['name'].should == [
'can\'t be blank',
'is too short (minimum is 0 characters)',
- 'can contain only letters, digits, \'_\', \'-\' and \'.\' and '\
- 'space. It must start with letter, digit or \'_\'.'
+ Gitlab::Regex.project_regex_message
]
json_response['message']['path'].should == [
'can\'t be blank',
'is too short (minimum is 0 characters)',
- 'can contain only letters, digits, \'_\', \'-\' and \'.\'. ' \
- 'Cannot start with \'-\' or end in \'.git\''
+ Gitlab::Regex.send(:default_regex_message)
]
end
diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb
index dd7a0fc6cc8..beae71c02d9 100644
--- a/spec/requests/api/repositories_spec.rb
+++ b/spec/requests/api/repositories_spec.rb
@@ -37,8 +37,7 @@ describe API::API, api: true do
context 'annotated tag' do
it 'should create a new annotated tag' do
# Identity must be set in .gitconfig to create annotated tag.
- repo_path = File.join(Gitlab.config.gitlab_shell.repos_path,
- project.path_with_namespace + '.git')
+ repo_path = project.repository.path_to_repo
system(*%W(git --git-dir=#{repo_path} config user.name #{user.name}))
system(*%W(git --git-dir=#{repo_path} config user.email #{user.email}))
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index a1a26d80a14..113a39b870e 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -140,8 +140,7 @@ describe API::API, api: true do
json_response['message']['projects_limit'].
should == ['must be greater than or equal to 0']
json_response['message']['username'].
- should == ['can contain only letters, digits, '\
- '\'_\', \'-\' and \'.\'. Cannot start with \'-\' or end in \'.git\'']
+ should == [Gitlab::Regex.send(:default_regex_message)]
end
it "shouldn't available for non admin users" do
@@ -283,8 +282,7 @@ describe API::API, api: true do
json_response['message']['projects_limit'].
should == ['must be greater than or equal to 0']
json_response['message']['username'].
- should == ['can contain only letters, digits, '\
- '\'_\', \'-\' and \'.\'. Cannot start with \'-\' or end in \'.git\'']
+ should == [Gitlab::Regex.send(:default_regex_message)]
end
context "with existing user" do
diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb
new file mode 100644
index 00000000000..9f294152053
--- /dev/null
+++ b/spec/services/merge_requests/refresh_service_spec.rb
@@ -0,0 +1,98 @@
+require 'spec_helper'
+
+describe MergeRequests::RefreshService do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+ let(:service) { MergeRequests::RefreshService }
+
+ describe :execute do
+ before do
+ @user = create(:user)
+ group = create(:group)
+ group.add_owner(@user)
+
+ @project = create(:project, namespace: group)
+ @fork_project = Projects::ForkService.new(@project, @user).execute
+ @merge_request = create(:merge_request, source_project: @project,
+ source_branch: 'master',
+ target_branch: 'feature',
+ target_project: @project)
+
+ @fork_merge_request = create(:merge_request, source_project: @fork_project,
+ source_branch: 'master',
+ target_branch: 'feature',
+ target_project: @project)
+
+ @commits = @merge_request.commits
+
+ @oldrev = @commits.last.id
+ @newrev = @commits.first.id
+ end
+
+ context 'push to origin repo source branch' do
+ before do
+ service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/master')
+ reload_mrs
+ end
+
+ it { @merge_request.notes.should_not be_empty }
+ it { @merge_request.should be_open }
+ it { @fork_merge_request.should be_open }
+ it { @fork_merge_request.notes.should be_empty }
+ end
+
+ context 'push to origin repo target branch' do
+ before do
+ service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/feature')
+ reload_mrs
+ end
+
+ it { @merge_request.notes.should be_empty }
+ it { @merge_request.should be_merged }
+ it { @fork_merge_request.should be_merged }
+ it { @fork_merge_request.notes.should be_empty }
+ end
+
+ context 'push to fork repo source branch' do
+ before do
+ service.new(@fork_project, @user).execute(@oldrev, @newrev, 'refs/heads/master')
+ reload_mrs
+ end
+
+ it { @merge_request.notes.should be_empty }
+ it { @merge_request.should be_open }
+ it { @fork_merge_request.notes.should_not be_empty }
+ it { @fork_merge_request.should be_open }
+ end
+
+ context 'push to fork repo target branch' do
+ before do
+ service.new(@fork_project, @user).execute(@oldrev, @newrev, 'refs/heads/feature')
+ reload_mrs
+ end
+
+ it { @merge_request.notes.should be_empty }
+ it { @merge_request.should be_open }
+ it { @fork_merge_request.notes.should be_empty }
+ it { @fork_merge_request.should be_open }
+ end
+
+ context 'push to origin repo target branch after fork project was removed' do
+ before do
+ @fork_project.destroy
+ service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/feature')
+ reload_mrs
+ end
+
+ it { @merge_request.notes.should be_empty }
+ it { @merge_request.should be_merged }
+ it { @fork_merge_request.should be_open }
+ it { @fork_merge_request.notes.should be_empty }
+ end
+
+ def reload_mrs
+ @merge_request.reload
+ @fork_merge_request.reload
+ end
+ end
+end