Commit b7d83acf authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

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

parents 253a017b e577bf2d
...@@ -21,6 +21,7 @@ v 8.8.0 (unreleased) ...@@ -21,6 +21,7 @@ v 8.8.0 (unreleased)
- Bump mail_room to 0.7.0 to fix stuck IDLE connections - Bump mail_room to 0.7.0 to fix stuck IDLE connections
- Remove future dates from contribution calendar graph. - Remove future dates from contribution calendar graph.
- Support e-mail notifications for comments on project snippets - Support e-mail notifications for comments on project snippets
- Fix API leak of notes of unauthorized issues, snippets and merge requests
- Use ActionDispatch Remote IP for Akismet checking - Use ActionDispatch Remote IP for Akismet checking
- Fix error when visiting commit builds page before build was updated - Fix error when visiting commit builds page before build was updated
- Add 'l' shortcut to open Label dropdown on issuables and 'i' to create new issue on a project - Add 'l' shortcut to open Label dropdown on issuables and 'i' to create new issue on a project
...@@ -38,6 +39,7 @@ v 8.8.0 (unreleased) ...@@ -38,6 +39,7 @@ v 8.8.0 (unreleased)
- Create tags using Rugged for performance reasons. !3745 - Create tags using Rugged for performance reasons. !3745
- API: Expose Issue#user_notes_count. !3126 (Anton Popov) - API: Expose Issue#user_notes_count. !3126 (Anton Popov)
- Don't show forks button when user can't view forks - Don't show forks button when user can't view forks
- Fix atom feed links and rendering
- Files over 5MB can only be viewed in their raw form, files over 1MB without highlighting !3718 - Files over 5MB can only be viewed in their raw form, files over 1MB without highlighting !3718
- Add support for supressing text diffs using .gitattributes on the default branch (Matt Oakes) - Add support for supressing text diffs using .gitattributes on the default branch (Matt Oakes)
- Add eager load paths to help prevent dependency load issues in Sidekiq workers. !3724 - Add eager load paths to help prevent dependency load issues in Sidekiq workers. !3724
...@@ -57,9 +59,13 @@ v 8.8.0 (unreleased) ...@@ -57,9 +59,13 @@ v 8.8.0 (unreleased)
- Redesign navigation for profile and group pages - Redesign navigation for profile and group pages
- Add counter metrics for rails cache - Add counter metrics for rails cache
- Import pull requests from GitHub where the source or target branches were removed - Import pull requests from GitHub where the source or target branches were removed
- All Grape API helpers are now instrumented
- Improve Issue formatting for the Slack Service (Jeroen van Baarsen)
v 8.7.6 v 8.7.6
- Fix links on wiki pages for relative url setups. !4131 (Artem Sidorenko) - Fix links on wiki pages for relative url setups. !4131 (Artem Sidorenko)
- Fix import from GitLab.com to a private instance failure. !4181
- Fix external imports not finding the import data. !4106
v 8.7.5 v 8.7.5
- Fix relative links in wiki pages. !4050 - Fix relative links in wiki pages. !4050
...@@ -889,7 +895,7 @@ v 8.1.3 ...@@ -889,7 +895,7 @@ v 8.1.3
- Use issue editor as cross reference comment author when issue is edited with a new mention - Use issue editor as cross reference comment author when issue is edited with a new mention
- Add Facebook authentication - Add Facebook authentication
v 8.1.2 v 8.1.1
- Fix cloning Wiki repositories via HTTP (Stan Hu) - Fix cloning Wiki repositories via HTTP (Stan Hu)
- Add migration to remove satellites directory - Add migration to remove satellites directory
- Fix specific runners visibility - Fix specific runners visibility
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
} }
} }
.zen-cotrol { .zen-control {
padding: 0; padding: 0;
color: #555; color: #555;
background: none; background: none;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
} }
.no-ssh-key-message, .project-limit-message { .no-ssh-key-message, .project-limit-message {
background-color: #f28d35; background-color: #f28d35;
margin-bottom: 16px; margin-bottom: 0;
} }
.new_project, .new_project,
.edit_project { .edit_project {
......
...@@ -20,6 +20,7 @@ class Projects::ImportsController < Projects::ApplicationController ...@@ -20,6 +20,7 @@ class Projects::ImportsController < Projects::ApplicationController
@project.import_retry @project.import_retry
else else
@project.import_start @project.import_start
@project.add_import_job
end end
end end
......
...@@ -204,7 +204,6 @@ class Project < ActiveRecord::Base ...@@ -204,7 +204,6 @@ class Project < ActiveRecord::Base
state :finished state :finished
state :failed state :failed
after_transition any => :started, do: :schedule_add_import_job
after_transition any => :finished, do: :clear_import_data after_transition any => :finished, do: :clear_import_data
end end
...@@ -349,10 +348,6 @@ class Project < ActiveRecord::Base ...@@ -349,10 +348,6 @@ class Project < ActiveRecord::Base
id && persisted? id && persisted?
end end
def schedule_add_import_job
run_after_commit(:add_import_job)
end
def add_import_job def add_import_job
if forked? if forked?
job_id = RepositoryForkWorker.perform_async(self.id, forked_from_project.path_with_namespace, self.namespace.path) job_id = RepositoryForkWorker.perform_async(self.id, forked_from_project.path_with_namespace, self.namespace.path)
......
...@@ -34,7 +34,12 @@ class SlackService ...@@ -34,7 +34,12 @@ class SlackService
private private
def message def message
"#{user_name} #{state} #{issue_link} in #{project_link}: *#{title}*" case state
when "opened"
"[#{project_link}] Issue #{state} by #{user_name}"
else
"[#{project_link}] Issue #{issue_link} #{state} by #{user_name}"
end
end end
def opened_issue? def opened_issue?
...@@ -42,7 +47,11 @@ class SlackService ...@@ -42,7 +47,11 @@ class SlackService
end end
def description_message def description_message
[{ text: format(description), color: attachment_color }] [{
title: issue_title,
title_link: issue_url,
text: format(description),
color: "#C95823" }]
end end
def project_link def project_link
...@@ -50,7 +59,11 @@ class SlackService ...@@ -50,7 +59,11 @@ class SlackService
end end
def issue_link def issue_link
"[issue ##{issue_iid}](#{issue_url})" "[#{issue_title}](#{issue_url})"
end
def issue_title
"##{issue_iid} #{title}"
end end
end end
end end
...@@ -6,6 +6,7 @@ module Projects ...@@ -6,6 +6,7 @@ module Projects
def execute def execute
forked_from_project_id = params.delete(:forked_from_project_id) forked_from_project_id = params.delete(:forked_from_project_id)
import_data = params.delete(:import_data)
@project = Project.new(params) @project = Project.new(params)
...@@ -49,16 +50,14 @@ module Projects ...@@ -49,16 +50,14 @@ module Projects
@project.build_forked_project_link(forked_from_project_id: forked_from_project_id) @project.build_forked_project_link(forked_from_project_id: forked_from_project_id)
end end
Project.transaction do save_project_and_import_data(import_data)
@project.save
if @project.persisted? && !@project.import? @project.import_start if @project.import?
raise 'Failed to create repository' unless @project.create_repository
end
end
after_create_actions if @project.persisted? after_create_actions if @project.persisted?
@project.add_import_job if @project.import?
@project @project
rescue => e rescue => e
message = "Unable to save project: #{e.message}" message = "Unable to save project: #{e.message}"
...@@ -93,8 +92,16 @@ module Projects ...@@ -93,8 +92,16 @@ module Projects
unless @project.group unless @project.group
@project.team << [current_user, :master, current_user] @project.team << [current_user, :master, current_user]
end end
end
@project.import_start if @project.import? def save_project_and_import_data(import_data)
Project.transaction do
@project.create_or_update_import_data(data: import_data[:data], credentials: import_data[:credentials]) if import_data
if @project.save && !@project.import?
raise 'Failed to create repository' unless @project.create_repository
end
end
end end
end end
end end
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
.nav-block .nav-block
- if current_user - if current_user
.controls .controls
= link_to dashboard_projects_path(:atom, { private_token: current_user.private_token }), class: 'btn rss-btn' do = link_to group_path(@group, format: :atom, private_token: current_user.private_token), class: 'btn rss-btn' do
%i.fa.fa-rss %i.fa.fa-rss
= render 'shared/event_filter' = render 'shared/event_filter'
......
xml.instruct! xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "#{@user.name} issues" xml.title "#{@group.name} issues"
xml.link href: issues_dashboard_url(format: :atom, private_token: @user.private_token), rel: "self", type: "application/atom+xml" xml.link href: issues_group_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml"
xml.link href: issues_dashboard_url, rel: "alternate", type: "text/html" xml.link href: issues_group_url, rel: "alternate", type: "text/html"
xml.id issues_dashboard_url xml.id issues_group_url
xml.updated @issues.first.created_at.xmlschema if @issues.any? xml.updated @issues.first.created_at.xmlschema if @issues.any?
@issues.each do |issue| @issues.each do |issue|
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
%a.js-md-preview-button{ href: "#md-preview-holder", tabindex: -1 } %a.js-md-preview-button{ href: "#md-preview-holder", tabindex: -1 }
Preview Preview
%li.pull-right %li.pull-right
%button.zen-cotrol.zen-control-full.js-zen-enter{ type: 'button', tabindex: -1 } %button.zen-control.zen-control-full.js-zen-enter{ type: 'button', tabindex: -1 }
Go full screen Go full screen
.md-write-holder .md-write-holder
......
...@@ -4,5 +4,5 @@ ...@@ -4,5 +4,5 @@
= f.text_area attr, class: classes, placeholder: placeholder = f.text_area attr, class: classes, placeholder: placeholder
- else - else
= text_area_tag attr, nil, class: classes, placeholder: placeholder = text_area_tag attr, nil, class: classes, placeholder: placeholder
%a.zen-cotrol.zen-control-leave.js-zen-leave{ href: "#" } %a.zen-control.zen-control-leave.js-zen-leave{ href: "#" }
= icon('compress') = icon('compress')
...@@ -118,6 +118,8 @@ if Gitlab::Metrics.enabled? ...@@ -118,6 +118,8 @@ if Gitlab::Metrics.enabled?
# Instrument the classes used for checking if somebody has push access. # Instrument the classes used for checking if somebody has push access.
config.instrument_instance_methods(Gitlab::GitAccess) config.instrument_instance_methods(Gitlab::GitAccess)
config.instrument_instance_methods(Gitlab::GitAccessWiki) config.instrument_instance_methods(Gitlab::GitAccessWiki)
config.instrument_instance_methods(API::Helpers)
end end
GC::Profiler.enable GC::Profiler.enable
......
...@@ -33,7 +33,7 @@ following locations: ...@@ -33,7 +33,7 @@ following locations:
- [Build triggers](build_triggers.md) - [Build triggers](build_triggers.md)
- [Build Variables](build_variables.md) - [Build Variables](build_variables.md)
- [Runners](runners.md) - [Runners](runners.md)
- [Licenses](licenses.md) - [Open source license templates](licenses.md)
## Authentication ## Authentication
......
...@@ -212,8 +212,8 @@ If you want to receive e-mail notifications about the result status of the ...@@ -212,8 +212,8 @@ If you want to receive e-mail notifications about the result status of the
builds, you should explicitly enable the **Builds Emails** service under your builds, you should explicitly enable the **Builds Emails** service under your
project's settings. project's settings.
For more information read the [Builds emails service documentation] For more information read the
(../../project_services/builds_emails.md). [Builds emails service documentation](../../project_services/builds_emails.md).
## Builds badge ## Builds badge
......
...@@ -19,20 +19,24 @@ module API ...@@ -19,20 +19,24 @@ module API
# GET /projects/:id/issues/:noteable_id/notes # GET /projects/:id/issues/:noteable_id/notes
# GET /projects/:id/snippets/:noteable_id/notes # GET /projects/:id/snippets/:noteable_id/notes
get ":id/#{noteables_str}/:#{noteable_id_str}/notes" do get ":id/#{noteables_str}/:#{noteable_id_str}/notes" do
@noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"]) @noteable = user_project.send(noteables_str.to_sym).find(params[noteable_id_str.to_sym])
# We exclude notes that are cross-references and that cannot be viewed if can?(current_user, noteable_read_ability_name(@noteable), @noteable)
# by the current user. By doing this exclusion at this level and not # We exclude notes that are cross-references and that cannot be viewed
# at the DB query level (which we cannot in that case), the current # by the current user. By doing this exclusion at this level and not
# page can have less elements than :per_page even if # at the DB query level (which we cannot in that case), the current
# there's more than one page. # page can have less elements than :per_page even if
notes = # there's more than one page.
# paginate() only works with a relation. This could lead to a notes =
# mismatch between the pagination headers info and the actual notes # paginate() only works with a relation. This could lead to a
# array returned, but this is really a edge-case. # mismatch between the pagination headers info and the actual notes
paginate(@noteable.notes). # array returned, but this is really a edge-case.
reject { |n| n.cross_reference_not_visible_for?(current_user) } paginate(@noteable.notes).
present notes, with: Entities::Note reject { |n| n.cross_reference_not_visible_for?(current_user) }
present notes, with: Entities::Note
else
not_found!("Notes")
end
end end
# Get a single +noteable+ note # Get a single +noteable+ note
...@@ -45,13 +49,14 @@ module API ...@@ -45,13 +49,14 @@ module API
# GET /projects/:id/issues/:noteable_id/notes/:note_id # GET /projects/:id/issues/:noteable_id/notes/:note_id
# GET /projects/:id/snippets/:noteable_id/notes/:note_id # GET /projects/:id/snippets/:noteable_id/notes/:note_id
get ":id/#{noteables_str}/:#{noteable_id_str}/notes/:note_id" do get ":id/#{noteables_str}/:#{noteable_id_str}/notes/:note_id" do
@noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"]) @noteable = user_project.send(noteables_str.to_sym).find(params[noteable_id_str.to_sym])
@note = @noteable.notes.find(params[:note_id]) @note = @noteable.notes.find(params[:note_id])
can_read_note = can?(current_user, noteable_read_ability_name(@noteable), @noteable) && !@note.cross_reference_not_visible_for?(current_user)
if @note.cross_reference_not_visible_for?(current_user) if can_read_note
not_found!("Note")
else
present @note, with: Entities::Note present @note, with: Entities::Note
else
not_found!("Note")
end end
end end
...@@ -136,5 +141,11 @@ module API ...@@ -136,5 +141,11 @@ module API
end end
end end
end end
helpers do
def noteable_read_ability_name(noteable)
"read_#{noteable.class.to_s.underscore.downcase}".to_sym
end
end
end end
end end
...@@ -11,7 +11,7 @@ module Gitlab ...@@ -11,7 +11,7 @@ module Gitlab
end end
def execute def execute
project = ::Projects::CreateService.new( ::Projects::CreateService.new(
current_user, current_user,
name: repo["name"], name: repo["name"],
path: repo["slug"], path: repo["slug"],
...@@ -21,11 +21,8 @@ module Gitlab ...@@ -21,11 +21,8 @@ module Gitlab
import_type: "bitbucket", import_type: "bitbucket",
import_source: "#{repo["owner"]}/#{repo["slug"]}", import_source: "#{repo["owner"]}/#{repo["slug"]}",
import_url: "ssh://git@bitbucket.org/#{repo["owner"]}/#{repo["slug"]}.git", import_url: "ssh://git@bitbucket.org/#{repo["owner"]}/#{repo["slug"]}.git",
import_data: { credentials: { bb_session: session_data } }
).execute ).execute
project.create_or_update_import_data(credentials: { bb_session: session_data })
project
end end
end end
end end
......
...@@ -12,7 +12,7 @@ module Gitlab ...@@ -12,7 +12,7 @@ module Gitlab
end end
def execute def execute
project = ::Projects::CreateService.new( ::Projects::CreateService.new(
current_user, current_user,
name: repo.safe_name, name: repo.safe_name,
path: repo.path, path: repo.path,
...@@ -21,12 +21,9 @@ module Gitlab ...@@ -21,12 +21,9 @@ module Gitlab
visibility_level: Gitlab::VisibilityLevel::INTERNAL, visibility_level: Gitlab::VisibilityLevel::INTERNAL,
import_type: 'fogbugz', import_type: 'fogbugz',
import_source: repo.name, import_source: repo.name,
import_url: Project::UNKNOWN_IMPORT_URL import_url: Project::UNKNOWN_IMPORT_URL,
import_data: { data: { 'repo' => repo.raw_data, 'user_map' => user_map }, credentials: { fb_session: fb_session } }
).execute ).execute
project.create_or_update_import_data(data: { 'repo' => repo.raw_data, 'user_map' => user_map }, credentials: { fb_session: fb_session })
project
end end
end end
end end
......
...@@ -5,7 +5,7 @@ module Gitlab ...@@ -5,7 +5,7 @@ module Gitlab
def initialize(project) def initialize(project)
@project = project @project = project
credentials = import_data credentials = project.import_data
if credentials && credentials[:password] if credentials && credentials[:password]
@client = Client.new(credentials[:password]) @client = Client.new(credentials[:password])
@formatter = Gitlab::ImportFormatter.new @formatter = Gitlab::ImportFormatter.new
......
...@@ -11,7 +11,7 @@ module Gitlab ...@@ -11,7 +11,7 @@ module Gitlab
end end
def execute def execute
project = ::Projects::CreateService.new( ::Projects::CreateService.new(
current_user, current_user,
name: repo.name, name: repo.name,
path: repo.name, path: repo.name,
...@@ -21,12 +21,9 @@ module Gitlab ...@@ -21,12 +21,9 @@ module Gitlab
visibility_level: Gitlab::VisibilityLevel::PUBLIC, visibility_level: Gitlab::VisibilityLevel::PUBLIC,
import_type: "google_code", import_type: "google_code",
import_source: repo.name, import_source: repo.name,
import_url: repo.import_url import_url: repo.import_url,
import_data: { data: { 'repo' => repo.raw_data, 'user_map' => user_map } }
).execute ).execute
project.create_or_update_import_data(data: { 'repo' => repo.raw_data, 'user_map' => user_map })
project
end end
end end
end end
......
...@@ -25,7 +25,7 @@ describe SlackService::IssueMessage, models: true do ...@@ -25,7 +25,7 @@ describe SlackService::IssueMessage, models: true do
} }
end end
let(:color) { '#345' } let(:color) { '#C95823' }
context '#initialize' do context '#initialize' do
before do before do
...@@ -40,10 +40,11 @@ describe SlackService::IssueMessage, models: true do ...@@ -40,10 +40,11 @@ describe SlackService::IssueMessage, models: true do
context 'open' do context 'open' do
it 'returns a message regarding opening of issues' do it 'returns a message regarding opening of issues' do
expect(subject.pretext).to eq( expect(subject.pretext).to eq(
'Test User opened <url|issue #100> in <somewhere.com|project_name>: '\ '<somewhere.com|[project_name>] Issue opened by Test User')
'*Issue title*')
expect(subject.attachments).to eq([ expect(subject.attachments).to eq([
{ {
title: "#100 Issue title",
title_link: "url",
text: "issue description", text: "issue description",
color: color, color: color,
} }
...@@ -56,10 +57,10 @@ describe SlackService::IssueMessage, models: true do ...@@ -56,10 +57,10 @@ describe SlackService::IssueMessage, models: true do
args[:object_attributes][:action] = 'close' args[:object_attributes][:action] = 'close'
args[:object_attributes][:state] = 'closed' args[:object_attributes][:state] = 'closed'
end end
it 'returns a message regarding closing of issues' do it 'returns a message regarding closing of issues' do
expect(subject.pretext). to eq( expect(subject.pretext). to eq(
'Test User closed <url|issue #100> in <somewhere.com|project_name>: '\ '<somewhere.com|[project_name>] Issue <url|#100 Issue title> closed by Test User')
'*Issue title*')
expect(subject.attachments).to be_empty expect(subject.attachments).to be_empty
end end
end end
......
This diff is collapsed.
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