summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG3
-rw-r--r--app/assets/javascripts/dropzone_input.js.coffee14
-rw-r--r--app/models/project_services/builds_email_service.rb6
-rw-r--r--app/services/projects/download_service.rb8
-rw-r--r--app/services/projects/upload_service.rb8
-rw-r--r--app/uploaders/file_uploader.rb15
-rw-r--r--app/validators/namespace_validator.rb1
-rw-r--r--app/views/admin/abuse_reports/_abuse_report.html.haml5
-rw-r--r--doc/api/projects.md28
-rw-r--r--lib/api/projects.rb12
-rw-r--r--lib/gitlab/build_data_builder.rb1
-rw-r--r--lib/gitlab/email/receiver.rb7
-rw-r--r--lib/gitlab/fogbugz_import/importer.rb4
-rw-r--r--spec/lib/gitlab/build_data_builder_spec.rb1
-rw-r--r--spec/lib/gitlab/email/receiver_spec.rb11
-rw-r--r--spec/models/project_services/builds_email_service_spec.rb23
-rw-r--r--spec/requests/api/projects_spec.rb14
-rw-r--r--spec/services/projects/download_service_spec.rb24
18 files changed, 132 insertions, 53 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 52cc8489d4f..921dac01264 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
Please view this file on the master branch, on stable branches it's out of date.
v 8.4.0 (unreleased)
+ - The default GitLab logo now acts as a loading indicator
- Accept 2xx status codes for successful Web hook triggers (Stan Hu)
- Fix missing date of month in network graph when commits span a month (Stan Hu)
- Expire view caches when application settings change (e.g. Gravatar disabled) (Stan Hu)
@@ -21,6 +22,7 @@ v 8.4.0 (unreleased)
- Add system hook messages for project rename and transfer (Steve Norman)
- Fix version check image in Safari
- Show 'All' tab by default in the builds page
+ - Add Open Graph and Twitter Card data to all pages
- Fix API project lookups when querying with a namespace with dots (Stan Hu)
- Update version check images to use SVG
- Validate README format before displaying
@@ -32,6 +34,7 @@ v 8.4.0 (unreleased)
v 8.3.3 (unreleased)
- Get "Merge when build succeeds" to work when commits were pushed to MR target branch while builds were running
+ - Suppress e-mails on failed builds if allow_failure is set (Stan Hu)
- Fix project transfer e-mail sending incorrect paths in e-mail notification (Stan Hu)
- Enable "Add key" button when user fills in a proper key (Stan Hu)
diff --git a/app/assets/javascripts/dropzone_input.js.coffee b/app/assets/javascripts/dropzone_input.js.coffee
index 30a35a04339..c714c0fa939 100644
--- a/app/assets/javascripts/dropzone_input.js.coffee
+++ b/app/assets/javascripts/dropzone_input.js.coffee
@@ -66,7 +66,7 @@ class @DropzoneInput
success: (header, response) ->
child = $(dropzone[0]).children("textarea")
- $(child).val $(child).val() + formatLink(response.link) + "\n"
+ $(child).val $(child).val() + response.link.markdown + "\n"
return
error: (temp, errorMessage) ->
@@ -99,11 +99,6 @@ class @DropzoneInput
child = $(dropzone[0]).children("textarea")
- formatLink = (link) ->
- text = "[#{link.alt}](#{link.url})"
- text = "!#{text}" if link.is_image
- text
-
handlePaste = (event) ->
pasteEvent = event.originalEvent
if pasteEvent.clipboardData and pasteEvent.clipboardData.items
@@ -162,7 +157,7 @@ class @DropzoneInput
closeAlertMessage()
success: (e, textStatus, response) ->
- insertToTextArea(filename, formatLink(response.responseJSON.link))
+ insertToTextArea(filename, response.responseJSON.link.markdown)
error: (response) ->
showError(response.responseJSON.message)
@@ -202,8 +197,3 @@ class @DropzoneInput
e.preventDefault()
$(@).closest('.gfm-form').find('.div-dropzone').click()
return
-
- formatLink: (link) ->
- text = "[#{link.alt}](#{link.url})"
- text = "!#{text}" if link.is_image
- text
diff --git a/app/models/project_services/builds_email_service.rb b/app/models/project_services/builds_email_service.rb
index 92c9b13c9b9..f6313255cbb 100644
--- a/app/models/project_services/builds_email_service.rb
+++ b/app/models/project_services/builds_email_service.rb
@@ -73,12 +73,16 @@ class BuildsEmailService < Service
when 'success'
!notify_only_broken_builds?
when 'failed'
- true
+ !allow_failure?(data)
else
false
end
end
+ def allow_failure?(data)
+ data[:build_allow_failure] == true
+ end
+
def all_recipients(data)
all_recipients = recipients.split(',')
diff --git a/app/services/projects/download_service.rb b/app/services/projects/download_service.rb
index 99f22293d0d..6386f57fb0d 100644
--- a/app/services/projects/download_service.rb
+++ b/app/services/projects/download_service.rb
@@ -16,13 +16,7 @@ module Projects
uploader.download!(@url)
uploader.store!
- filename = uploader.image? ? uploader.file.basename : uploader.file.filename
-
- {
- 'alt' => filename,
- 'url' => uploader.secure_url,
- 'is_image' => uploader.image?
- }
+ uploader.to_h
end
private
diff --git a/app/services/projects/upload_service.rb b/app/services/projects/upload_service.rb
index 279550d6f4a..012e82a7704 100644
--- a/app/services/projects/upload_service.rb
+++ b/app/services/projects/upload_service.rb
@@ -10,13 +10,7 @@ module Projects
uploader = FileUploader.new(@project)
uploader.store!(@file)
- filename = uploader.image? ? uploader.file.basename : uploader.file.filename
-
- {
- alt: filename,
- url: uploader.secure_url,
- is_image: uploader.image?
- }
+ uploader.to_h
end
private
diff --git a/app/uploaders/file_uploader.rb b/app/uploaders/file_uploader.rb
index ac920119a85..86d24469e05 100644
--- a/app/uploaders/file_uploader.rb
+++ b/app/uploaders/file_uploader.rb
@@ -30,4 +30,19 @@ class FileUploader < CarrierWave::Uploader::Base
def secure_url
File.join("/uploads", @secret, file.filename)
end
+
+ def to_h
+ filename = image? ? self.file.basename : self.file.filename
+ escaped_filename = filename.gsub("]", "\\]")
+
+ markdown = "[#{escaped_filename}](#{self.secure_url})"
+ markdown.prepend("!") if image?
+
+ {
+ alt: filename,
+ url: self.secure_url,
+ is_image: image?,
+ markdown: markdown
+ }
+ end
end
diff --git a/app/validators/namespace_validator.rb b/app/validators/namespace_validator.rb
index 10e35ce665a..7a35958cc5f 100644
--- a/app/validators/namespace_validator.rb
+++ b/app/validators/namespace_validator.rb
@@ -17,6 +17,7 @@ class NamespaceValidator < ActiveModel::EachValidator
hooks
issues
merge_requests
+ new
notes
profile
projects
diff --git a/app/views/admin/abuse_reports/_abuse_report.html.haml b/app/views/admin/abuse_reports/_abuse_report.html.haml
index cf50a376e11..853a780c576 100644
--- a/app/views/admin/abuse_reports/_abuse_report.html.haml
+++ b/app/views/admin/abuse_reports/_abuse_report.html.haml
@@ -23,6 +23,9 @@
data: { confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?" }, remote: true, method: :delete, class: "btn btn-xs btn-remove js-remove-tr"
%td
- - if user
+ - if user && !user.blocked?
= link_to 'Block user', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-xs"
+ - else
+ .btn.btn-xs
+ Already Blocked
= link_to 'Remove report', [:admin, abuse_report], remote: true, method: :delete, class: "btn btn-xs btn-close js-remove-tr"
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 0ca81ffd49e..37d74216c1b 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -482,6 +482,34 @@ Parameters:
- `id` (required) - The ID of a project
+## Uploads
+
+### Upload a file
+
+Uploads a file to the specified project to be used in an issue or merge request description, or a comment.
+
+```
+POST /projects/:id/uploads
+```
+
+Parameters:
+
+- `id` (required) - The ID of the project
+- `file` (required) - The file to be uploaded
+
+```json
+{
+ "alt": "dk",
+ "url": "/uploads/66dbcd21ec5d24ed6ea225176098d52b/dk.png",
+ "is_image": true,
+ "markdown": "![dk](/uploads/66dbcd21ec5d24ed6ea225176098d52b/dk.png)"
+}
+```
+
+**Note**: The returned `url` is relative to the project path.
+In Markdown contexts, the link is automatically expanded when the format in `markdown` is used.
+
+
## Team members
### List project team members
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 0781236cf6d..8b1390e3289 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -269,7 +269,7 @@ module API
# Remove a forked_from relationship
#
# Parameters:
- # id: (required) - The ID of the project being marked as a fork
+ # id: (required) - The ID of the project being marked as a fork
# Example Request:
# DELETE /projects/:id/fork
delete ":id/fork" do
@@ -278,6 +278,16 @@ module API
user_project.forked_project_link.destroy
end
end
+
+ # Upload a file
+ #
+ # Parameters:
+ # id: (required) - The ID of the project
+ # file: (required) - The file to be uploaded
+ post ":id/uploads" do
+ ::Projects::UploadService.new(user_project, params[:file]).execute
+ end
+
# search for projects current_user has access to
#
# Parameters:
diff --git a/lib/gitlab/build_data_builder.rb b/lib/gitlab/build_data_builder.rb
index 86bfa0a4378..34e949130da 100644
--- a/lib/gitlab/build_data_builder.rb
+++ b/lib/gitlab/build_data_builder.rb
@@ -23,6 +23,7 @@ module Gitlab
build_started_at: build.started_at,
build_finished_at: build.finished_at,
build_duration: build.duration,
+ build_allow_failure: build.allow_failure,
# TODO: do we still need it?
project_id: project.id,
diff --git a/lib/gitlab/email/receiver.rb b/lib/gitlab/email/receiver.rb
index 2b252b32887..2ca21af5bc8 100644
--- a/lib/gitlab/email/receiver.rb
+++ b/lib/gitlab/email/receiver.rb
@@ -74,7 +74,7 @@ module Gitlab
def sent_notification
return nil unless reply_key
-
+
SentNotification.for(reply_key)
end
@@ -82,10 +82,7 @@ module Gitlab
attachments = Email::AttachmentUploader.new(message).execute(sent_notification.project)
attachments.each do |link|
- text = "[#{link[:alt]}](#{link[:url]})"
- text.prepend("!") if link[:is_image]
-
- reply << "\n\n#{text}"
+ reply << "\n\n#{link[:markdown]}"
end
reply
diff --git a/lib/gitlab/fogbugz_import/importer.rb b/lib/gitlab/fogbugz_import/importer.rb
index 403ebeec474..db580b5e578 100644
--- a/lib/gitlab/fogbugz_import/importer.rb
+++ b/lib/gitlab/fogbugz_import/importer.rb
@@ -232,9 +232,7 @@ module Gitlab
return nil if res.nil?
- text = "[#{res['alt']}](#{res['url']})"
- text = "!#{text}" if res['is_image']
- text
+ res[:markdown]
end
def build_attachment_url(rel_url)
diff --git a/spec/lib/gitlab/build_data_builder_spec.rb b/spec/lib/gitlab/build_data_builder_spec.rb
index 839b30f1ff4..38be9448794 100644
--- a/spec/lib/gitlab/build_data_builder_spec.rb
+++ b/spec/lib/gitlab/build_data_builder_spec.rb
@@ -14,6 +14,7 @@ describe 'Gitlab::BuildDataBuilder' do
it { expect(data[:tag]).to eq(build.tag) }
it { expect(data[:build_id]).to eq(build.id) }
it { expect(data[:build_status]).to eq(build.status) }
+ it { expect(data[:build_allow_failure]).to eq(false) }
it { expect(data[:project_id]).to eq(build.project.id) }
it { expect(data[:project_name]).to eq(build.project.name_with_namespace) }
end
diff --git a/spec/lib/gitlab/email/receiver_spec.rb b/spec/lib/gitlab/email/receiver_spec.rb
index b535413bbd4..abe179cd4af 100644
--- a/spec/lib/gitlab/email/receiver_spec.rb
+++ b/spec/lib/gitlab/email/receiver_spec.rb
@@ -42,7 +42,7 @@ describe Gitlab::Email::Receiver, lib: true do
context "when the email was auto generated" do
let!(:reply_key) { '636ca428858779856c226bb145ef4fad' }
let!(:email_raw) { fixture_file("emails/auto_reply.eml") }
-
+
it "raises an AutoGeneratedEmailError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::Receiver::AutoGeneratedEmailError)
end
@@ -90,7 +90,7 @@ describe Gitlab::Email::Receiver, lib: true do
context "when the reply is blank" do
let!(:email_raw) { fixture_file("emails/no_content_reply.eml") }
-
+
it "raises an EmptyEmailError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::Receiver::EmptyEmailError)
end
@@ -107,13 +107,16 @@ describe Gitlab::Email::Receiver, lib: true do
end
context "when everything is fine" do
+ let(:markdown) { "![image](uploads/image.png)" }
+
before do
allow_any_instance_of(Gitlab::Email::AttachmentUploader).to receive(:execute).and_return(
[
{
url: "uploads/image.png",
is_image: true,
- alt: "image"
+ alt: "image",
+ markdown: markdown
}
]
)
@@ -132,7 +135,7 @@ describe Gitlab::Email::Receiver, lib: true do
note = noteable.notes.last
- expect(note.note).to include("![image](uploads/image.png)")
+ expect(note.note).to include(markdown)
end
end
end
diff --git a/spec/models/project_services/builds_email_service_spec.rb b/spec/models/project_services/builds_email_service_spec.rb
new file mode 100644
index 00000000000..905379a64e3
--- /dev/null
+++ b/spec/models/project_services/builds_email_service_spec.rb
@@ -0,0 +1,23 @@
+require 'spec_helper'
+
+describe BuildsEmailService do
+ let(:build) { create(:ci_build) }
+ let(:data) { Gitlab::BuildDataBuilder.build(build) }
+ let(:service) { BuildsEmailService.new }
+
+ describe :execute do
+ it "sends email" do
+ service.recipients = 'test@gitlab.com'
+ data[:build_status] = 'failed'
+ expect(BuildEmailWorker).to receive(:perform_async)
+ service.execute(data)
+ end
+
+ it "does not sends email with failed build and allowed_failure on" do
+ data[:build_status] = 'failed'
+ data[:build_allow_failure] = true
+ expect(BuildEmailWorker).not_to receive(:perform_async)
+ service.execute(data)
+ end
+ end
+end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index ab2530859ea..6f4c336b66c 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -353,6 +353,20 @@ describe API::API, api: true do
end
end
+ describe "POST /projects/:id/uploads" do
+ before { project }
+
+ it "uploads the file and returns its info" do
+ post api("/projects/#{project.id}/uploads", user), file: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")
+
+ expect(response.status).to be(201)
+ expect(json_response['alt']).to eq("dk")
+ expect(json_response['url']).to start_with("/uploads/")
+ expect(json_response['url']).to end_with("/dk.png")
+ expect(json_response['is_image']).to eq(true)
+ end
+ end
+
describe 'GET /projects/:id' do
before { project }
before { project_member }
diff --git a/spec/services/projects/download_service_spec.rb b/spec/services/projects/download_service_spec.rb
index 5ceed5af9a5..f252e2c5902 100644
--- a/spec/services/projects/download_service_spec.rb
+++ b/spec/services/projects/download_service_spec.rb
@@ -33,12 +33,12 @@ describe Projects::DownloadService, services: true do
@link_to_file = download_file(@project, url)
end
- it { expect(@link_to_file).to have_key('alt') }
- it { expect(@link_to_file).to have_key('url') }
- it { expect(@link_to_file).to have_key('is_image') }
- it { expect(@link_to_file['is_image']).to be true }
- it { expect(@link_to_file['url']).to match('rails_sample.jpg') }
- it { expect(@link_to_file['alt']).to eq('rails_sample') }
+ it { expect(@link_to_file).to have_key(:alt) }
+ it { expect(@link_to_file).to have_key(:url) }
+ it { expect(@link_to_file).to have_key(:is_image) }
+ it { expect(@link_to_file[:is_image]).to be true }
+ it { expect(@link_to_file[:url]).to match('rails_sample.jpg') }
+ it { expect(@link_to_file[:alt]).to eq('rails_sample') }
end
context 'a txt file' do
@@ -47,12 +47,12 @@ describe Projects::DownloadService, services: true do
@link_to_file = download_file(@project, url)
end
- it { expect(@link_to_file).to have_key('alt') }
- it { expect(@link_to_file).to have_key('url') }
- it { expect(@link_to_file).to have_key('is_image') }
- it { expect(@link_to_file['is_image']).to be false }
- it { expect(@link_to_file['url']).to match('doc_sample.txt') }
- it { expect(@link_to_file['alt']).to eq('doc_sample.txt') }
+ it { expect(@link_to_file).to have_key(:alt) }
+ it { expect(@link_to_file).to have_key(:url) }
+ it { expect(@link_to_file).to have_key(:is_image) }
+ it { expect(@link_to_file[:is_image]).to be false }
+ it { expect(@link_to_file[:url]).to match('doc_sample.txt') }
+ it { expect(@link_to_file[:alt]).to eq('doc_sample.txt') }
end
end
end