diff options
Diffstat (limited to 'app/services')
23 files changed, 300 insertions, 240 deletions
diff --git a/app/services/ci/image_for_build_service.rb b/app/services/ci/image_for_build_service.rb index b95835ba093..b8d24193035 100644 --- a/app/services/ci/image_for_build_service.rb +++ b/app/services/ci/image_for_build_service.rb @@ -1,17 +1,15 @@ module Ci class ImageForBuildService def execute(project, params) - image_name = - if params[:sha] - commit = project.commits.find_by(sha: params[:sha]) - image_for_commit(commit) - elsif params[:ref] - commit = project.last_commit_for_ref(params[:ref]) - image_for_commit(commit) - else - 'build-unknown.svg' + sha = params[:sha] + sha ||= + if params[:ref] + project.gl_project.commit(params[:ref]).try(:sha) end + commit = project.commits.ordered.find_by(sha: sha) + image_name = image_for_commit(commit) + image_path = Rails.root.join('public/ci', image_name) OpenStruct.new( diff --git a/app/services/compare_service.rb b/app/services/compare_service.rb index bfe6a3dc4be..ec581658fc1 100644 --- a/app/services/compare_service.rb +++ b/app/services/compare_service.rb @@ -3,7 +3,7 @@ require 'securerandom' # Compare 2 branches for one repo or between repositories # and return Gitlab::CompareResult object that responds to commits and diffs class CompareService - def execute(source_project, source_branch, target_project, target_branch) + def execute(source_project, source_branch, target_project, target_branch, diff_options = {}) source_commit = source_project.commit(source_branch) return unless source_commit @@ -25,7 +25,7 @@ class CompareService target_project.repository.raw_repository, target_branch, source_sha, - ) + ), diff_options ) end end diff --git a/app/services/create_release_service.rb b/app/services/create_release_service.rb new file mode 100644 index 00000000000..e06a6f2f47a --- /dev/null +++ b/app/services/create_release_service.rb @@ -0,0 +1,31 @@ +require_relative 'base_service' + +class CreateReleaseService < BaseService + def execute(tag_name, release_description) + + repository = project.repository + existing_tag = repository.find_tag(tag_name) + + # Only create a release if the tag exists + if existing_tag + release = project.releases.find_by(tag: tag_name) + + if release + error('Release already exists', 409) + else + release = project.releases.new({ tag: tag_name, description: release_description }) + release.save + + success(release) + end + else + error('Tag does not exist', 404) + end + end + + def success(release) + out = super() + out[:release] = release + out + end +end diff --git a/app/services/create_tag_service.rb b/app/services/create_tag_service.rb index 1a7318048b3..2452999382a 100644 --- a/app/services/create_tag_service.rb +++ b/app/services/create_tag_service.rb @@ -1,7 +1,7 @@ require_relative 'base_service' class CreateTagService < BaseService - def execute(tag_name, ref, message) + def execute(tag_name, ref, message, release_description = nil) valid_tag = Gitlab::GitRefValidator.validate(tag_name) if valid_tag == false return error('Tag name invalid') @@ -20,11 +20,15 @@ class CreateTagService < BaseService if new_tag push_data = create_push_data(project, current_user, new_tag) - EventCreateService.new.push(project, current_user, push_data) project.execute_hooks(push_data.dup, :tag_push_hooks) project.execute_services(push_data.dup, :tag_push_hooks) + if release_description + CreateReleaseService.new(@project, @current_user). + execute(tag_name, release_description) + end + success(new_tag) else error('Invalid reference name') diff --git a/app/services/delete_tag_service.rb b/app/services/delete_tag_service.rb index 0c836401136..de3352a6756 100644 --- a/app/services/delete_tag_service.rb +++ b/app/services/delete_tag_service.rb @@ -11,8 +11,10 @@ class DeleteTagService < BaseService end if repository.rm_tag(tag_name) + release = project.releases.find_by(tag: tag_name) + release.destroy if release + push_data = build_push_data(tag) - EventCreateService.new.push(project, current_user, push_data) project.execute_hooks(push_data.dup, :tag_push_hooks) project.execute_services(push_data.dup, :tag_push_hooks) diff --git a/app/services/files/create_dir_service.rb b/app/services/files/create_dir_service.rb index 71272fb5707..6107254a34e 100644 --- a/app/services/files/create_dir_service.rb +++ b/app/services/files/create_dir_service.rb @@ -5,5 +5,16 @@ module Files def commit repository.commit_dir(current_user, @file_path, @commit_message, @target_branch) end + + def validate + super + + unless @file_path =~ Gitlab::Regex.file_path_regex + raise_error( + 'Your changes could not be committed, because the file path ' + + Gitlab::Regex.file_path_regex_message + ) + end + end end end diff --git a/app/services/files/create_service.rb b/app/services/files/create_service.rb index c8e3a910bba..2348920cc58 100644 --- a/app/services/files/create_service.rb +++ b/app/services/files/create_service.rb @@ -9,12 +9,17 @@ module Files def validate super - file_name = File.basename(@file_path) + if @file_path =~ Gitlab::Regex.directory_traversal_regex + raise_error( + 'Your changes could not be committed, because the file name ' + + Gitlab::Regex.directory_traversal_regex_message + ) + end - unless file_name =~ Gitlab::Regex.file_name_regex + unless @file_path =~ Gitlab::Regex.file_path_regex raise_error( 'Your changes could not be committed, because the file name ' + - Gitlab::Regex.file_name_regex_message + Gitlab::Regex.file_path_regex_message ) end diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index 3de7bb9dcaa..f11690aa3f4 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -58,12 +58,6 @@ class GitPushService @push_data = build_push_data(oldrev, newrev, ref) - # If CI was disabled but .gitlab-ci.yml file was pushed - # we enable CI automatically - if !project.gitlab_ci? && gitlab_ci_yaml?(newrev) - project.enable_ci - end - EventCreateService.new.push(project, user, @push_data) project.execute_hooks(@push_data.dup, :push_hooks) project.execute_services(@push_data.dup, :push_hooks) @@ -134,10 +128,4 @@ class GitPushService def commit_user(commit) commit.author || user end - - def gitlab_ci_yaml?(sha) - @project.repository.blob_at(sha, '.gitlab-ci.yml') - rescue Rugged::ReferenceError - nil - end end diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index 15b3825f96a..2556f06e2d3 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -27,7 +27,16 @@ class IssuableBaseService < BaseService old_branch, new_branch) end + def create_task_status_note(issuable) + issuable.updated_tasks.each do |task| + SystemNoteService.change_task_status(issuable, issuable.project, current_user, task) + end + end + def filter_params(issuable_ability_name = :issue) + params[:assignee_id] = "" if params[:assignee_id] == IssuableFinder::NONE + params[:milestone_id] = "" if params[:milestone_id] == IssuableFinder::NONE + ability = :"admin_#{issuable_ability_name}" unless can?(current_user, ability, project) @@ -36,4 +45,44 @@ class IssuableBaseService < BaseService params.delete(:assignee_id) end end + + def update(issuable) + change_state(issuable) + filter_params + old_labels = issuable.labels.to_a + + if params.present? && issuable.update_attributes(params.merge(updated_by: current_user)) + issuable.reset_events_cache + handle_common_system_notes(issuable, old_labels: old_labels) + handle_changes(issuable) + issuable.create_new_cross_references!(current_user) + execute_hooks(issuable, 'update') + end + + issuable + end + + def change_state(issuable) + case params.delete(:state_event) + when 'reopen' + reopen_service.new(project, current_user, {}).execute(issuable) + when 'close' + close_service.new(project, current_user, {}).execute(issuable) + end + end + + def handle_common_system_notes(issuable, options = {}) + if issuable.previous_changes.include?('title') + create_title_change_note(issuable, issuable.previous_changes['title'].first) + end + + if issuable.previous_changes.include?('description') && issuable.tasks? + create_task_status_note(issuable) + end + + old_labels = options[:old_labels] + if old_labels && (issuable.labels != old_labels) + create_labels_note(issuable, issuable.labels - old_labels, old_labels - issuable.labels) + end + end end diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb index 2b5426ad452..a55a04dd5e0 100644 --- a/app/services/issues/update_service.rb +++ b/app/services/issues/update_service.rb @@ -1,45 +1,26 @@ module Issues class UpdateService < Issues::BaseService def execute(issue) - case params.delete(:state_event) - when 'reopen' - Issues::ReopenService.new(project, current_user, {}).execute(issue) - when 'close' - Issues::CloseService.new(project, current_user, {}).execute(issue) - end - - params[:assignee_id] = "" if params[:assignee_id] == IssuableFinder::NONE - params[:milestone_id] = "" if params[:milestone_id] == IssuableFinder::NONE - - filter_params - old_labels = issue.labels.to_a - - if params.present? && issue.update_attributes(params.merge(updated_by: current_user)) - issue.reset_events_cache - - if issue.labels != old_labels - create_labels_note( - issue, issue.labels - old_labels, old_labels - issue.labels) - end - - if issue.previous_changes.include?('milestone_id') - create_milestone_note(issue) - end - - if issue.previous_changes.include?('assignee_id') - create_assignee_note(issue) - notification_service.reassigned_issue(issue, current_user) - end + update(issue) + end - if issue.previous_changes.include?('title') - create_title_change_note(issue, issue.previous_changes['title'].first) - end + def handle_changes(issue) + if issue.previous_changes.include?('milestone_id') + create_milestone_note(issue) + end - issue.create_new_cross_references! - execute_hooks(issue, 'update') + if issue.previous_changes.include?('assignee_id') + create_assignee_note(issue) + notification_service.reassigned_issue(issue, current_user) end + end + + def reopen_service + Issues::ReopenService + end - issue + def close_service + Issues::CloseService end end end diff --git a/app/services/labels/group_service.rb b/app/services/labels/group_service.rb deleted file mode 100644 index b26cee24d56..00000000000 --- a/app/services/labels/group_service.rb +++ /dev/null @@ -1,26 +0,0 @@ -module Labels - class GroupService < ::BaseService - def initialize(project_labels) - @project_labels = project_labels.group_by(&:title) - end - - def execute - build(@project_labels) - end - - def label(title) - if title - group_label = @project_labels[title].group_by(&:title) - build(group_label).first - else - nil - end - end - - private - - def build(label) - label.map { |title, labels| GroupLabel.new(title, labels) } - end - end -end diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index 7963af127e1..d619b72e3c2 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -38,7 +38,7 @@ module MergeRequests } repository.merge(current_user, merge_request.source_sha, merge_request.target_branch, options) - rescue Exception => e + rescue StandardError => e merge_request.update(merge_error: "Something went wrong during merge") Rails.logger.error(e.message) return false diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb index d68bc79ecc0..e180edb4bf3 100644 --- a/app/services/merge_requests/refresh_service.rb +++ b/app/services/merge_requests/refresh_service.rb @@ -7,17 +7,17 @@ module MergeRequests @branch_name = Gitlab::Git.ref_name(ref) find_new_commits + # Be sure to close outstanding MRs before reloading them to avoid generating an + # empty diff during a manual merge + close_merge_requests reload_merge_requests # Leave a system note if a branch was deleted/added if branch_added? || branch_removed? comment_mr_branch_presence_changed - comment_mr_with_commits - else - comment_mr_with_commits - close_merge_requests end + comment_mr_with_commits execute_mr_web_hooks true diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb index ebbe0af803b..5ff2cc03dda 100644 --- a/app/services/merge_requests/update_service.rb +++ b/app/services/merge_requests/update_service.rb @@ -11,59 +11,37 @@ module MergeRequests params.except!(:target_project_id) params.except!(:source_branch) - case params.delete(:state_event) - when 'reopen' - MergeRequests::ReopenService.new(project, current_user, {}).execute(merge_request) - when 'close' - MergeRequests::CloseService.new(project, current_user, {}).execute(merge_request) - end - - params[:assignee_id] = "" if params[:assignee_id] == IssuableFinder::NONE - params[:milestone_id] = "" if params[:milestone_id] == IssuableFinder::NONE - - filter_params - old_labels = merge_request.labels.to_a - - if params.present? && merge_request.update_attributes(params.merge(updated_by: current_user)) - merge_request.reset_events_cache - - if merge_request.labels != old_labels - create_labels_note( - merge_request, - merge_request.labels - old_labels, - old_labels - merge_request.labels - ) - end - - if merge_request.previous_changes.include?('target_branch') - create_branch_change_note(merge_request, 'target', - merge_request.previous_changes['target_branch'].first, - merge_request.target_branch) - end - - if merge_request.previous_changes.include?('milestone_id') - create_milestone_note(merge_request) - end + update(merge_request) + end - if merge_request.previous_changes.include?('assignee_id') - create_assignee_note(merge_request) - notification_service.reassigned_merge_request(merge_request, current_user) - end + def handle_changes(merge_request) + if merge_request.previous_changes.include?('target_branch') + create_branch_change_note(merge_request, 'target', + merge_request.previous_changes['target_branch'].first, + merge_request.target_branch) + end - if merge_request.previous_changes.include?('title') - create_title_change_note(merge_request, merge_request.previous_changes['title'].first) - end + if merge_request.previous_changes.include?('milestone_id') + create_milestone_note(merge_request) + end - if merge_request.previous_changes.include?('target_branch') || - merge_request.previous_changes.include?('source_branch') - merge_request.mark_as_unchecked - end + if merge_request.previous_changes.include?('assignee_id') + create_assignee_note(merge_request) + notification_service.reassigned_merge_request(merge_request, current_user) + end - merge_request.create_new_cross_references! - execute_hooks(merge_request, 'update') + if merge_request.previous_changes.include?('target_branch') || + merge_request.previous_changes.include?('source_branch') + merge_request.mark_as_unchecked end + end + + def reopen_service + MergeRequests::ReopenService + end - merge_request + def close_service + MergeRequests::CloseService end end end diff --git a/app/services/milestones/group_service.rb b/app/services/milestones/group_service.rb deleted file mode 100644 index 11d702f1e7b..00000000000 --- a/app/services/milestones/group_service.rb +++ /dev/null @@ -1,26 +0,0 @@ -module Milestones - class GroupService < Milestones::BaseService - def initialize(project_milestones) - @project_milestones = project_milestones.group_by(&:title) - end - - def execute - build(@project_milestones) - end - - def milestone(title) - if title - group_milestone = @project_milestones[title].group_by(&:title) - build(group_milestone).first - else - nil - end - end - - private - - def build(milestone) - milestone.map{ |title, milestones| GroupMilestone.new(title, milestones) } - end - end -end diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb index 2001dc89c33..dbff58dfb9c 100644 --- a/app/services/notes/create_service.rb +++ b/app/services/notes/create_service.rb @@ -5,11 +5,16 @@ module Notes note.author = current_user note.system = false + if contains_emoji_only?(params[:note]) + note.is_award = true + note.note = emoji_name(params[:note]) + end + if note.save notification_service.new_note(note) - # Skip system notes, like status changes and cross-references. - unless note.system + # Skip system notes, like status changes and cross-references and awards + unless note.system || note.is_award event_service.leave_note(note, note.author) note.create_cross_references! execute_hooks(note) @@ -28,5 +33,13 @@ module Notes note.project.execute_hooks(note_data, :note_hooks) note.project.execute_services(note_data, :note_hooks) end + + def contains_emoji_only?(note) + note =~ /\A:[-_+[:alnum:]]*:\s?\z/ + end + + def emoji_name(note) + note.match(/\A:([-_+[:alnum:]]*):\s?/)[1] + end end end diff --git a/app/services/notes/update_service.rb b/app/services/notes/update_service.rb index 6c2f08e5963..72e2f78008d 100644 --- a/app/services/notes/update_service.rb +++ b/app/services/notes/update_service.rb @@ -4,7 +4,7 @@ module Notes return note unless note.editable? note.update_attributes(params.merge(updated_by: current_user)) - note.create_new_cross_references! + note.create_new_cross_references!(current_user) note.reset_events_cache note diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index a6b22348650..d6550fbb555 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -102,6 +102,7 @@ class NotificationService # ignore gitlab service messages return true if note.note.start_with?('Status changed to closed') return true if note.cross_reference? && note.system == true + return true if note.is_award target = note.noteable @@ -113,7 +114,7 @@ class NotificationService end # Add all users participating in the thread (author, assignee, comment authors) - participants = + participants = if target.respond_to?(:participants) target.participants(note.author) else @@ -276,35 +277,25 @@ class NotificationService # Remove users with disabled notifications from array # Also remove duplications and nil recipients def reject_muted_users(users, project = nil) - users = users.to_a.compact.uniq - users = users.reject(&:blocked?) - - users.reject do |user| - next user.notification.disabled? unless project - - member = project.project_members.find_by(user_id: user.id) - - if !member && project.group - member = project.group.group_members.find_by(user_id: user.id) - end - - # reject users who globally disabled notification and has no membership - next user.notification.disabled? unless member - - # reject users who disabled notification in project - next true if member.notification.disabled? - - # reject users who have N_GLOBAL in project and disabled in global settings - member.notification.global? && user.notification.disabled? - end + reject_users(users, :disabled?, project) end # Remove users with notification level 'Mentioned' def reject_mention_users(users, project = nil) + reject_users(users, :mention?, project) + end + + # Reject users which method_name from notification object returns true. + # + # Example: + # reject_users(users, :watch?, project) + # + def reject_users(users, method_name, project = nil) users = users.to_a.compact.uniq + users = users.reject(&:blocked?) users.reject do |user| - next user.notification.mention? unless project + next user.notification.send(method_name) unless project member = project.project_members.find_by(user_id: user.id) @@ -313,19 +304,19 @@ class NotificationService end # reject users who globally set mention notification and has no membership - next user.notification.mention? unless member + next user.notification.send(method_name) unless member # reject users who set mention notification in project - next true if member.notification.mention? + next true if member.notification.send(method_name) # reject users who have N_MENTION in project and disabled in global settings - member.notification.global? && user.notification.mention? + member.notification.global? && user.notification.send(method_name) end end def reject_unsubscribed_users(recipients, target) return recipients unless target.respond_to? :subscriptions - + recipients.reject do |user| subscription = target.subscriptions.find_by_user_id(user.id) subscription && !subscription.subscribed @@ -343,7 +334,7 @@ class NotificationService recipients end end - + def new_resource_email(target, project, method) recipients = build_recipients(target, project, target.author) @@ -361,11 +352,13 @@ class NotificationService end def reassign_resource_email(target, project, current_user, method) - assignee_id_was = previous_record(target, "assignee_id") - recipients = build_recipients(target, project, current_user) + previous_assignee_id = previous_record(target, "assignee_id") + previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id + + recipients = build_recipients(target, project, current_user, [previous_assignee]) recipients.each do |recipient| - mailer.send(method, recipient.id, target.id, assignee_id_was, current_user.id) + mailer.send(method, recipient.id, target.id, previous_assignee_id, current_user.id) end end @@ -377,9 +370,11 @@ class NotificationService end end - def build_recipients(target, project, current_user) + def build_recipients(target, project, current_user, extra_recipients = nil) recipients = target.participants(current_user) + recipients = recipients.concat(extra_recipients).compact.uniq if extra_recipients + recipients = add_project_watchers(recipients, project) recipients = reject_mention_users(recipients, project) recipients = reject_muted_users(recipients, project) diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index faf1ee008e7..700a1db04d8 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -55,7 +55,9 @@ module Projects @project.save if @project.persisted? && !@project.import? - raise 'Failed to create repository' unless @project.create_repository + unless @project.create_repository + raise 'Failed to create repository' + end end end @@ -94,11 +96,7 @@ module Projects @project.team << [current_user, :master, current_user] end - @project.update_column(:last_activity_at, @project.created_at) - - if @project.import? - @project.import_start - end + @project.import_start if @project.import? end end end diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb index 46374a3909a..5da1c7afd92 100644 --- a/app/services/projects/fork_service.rb +++ b/app/services/projects/fork_service.rb @@ -17,7 +17,7 @@ module Projects new_project = CreateService.new(current_user, new_params).execute if new_project.persisted? - if @project.gitlab_ci? + if @project.builds_enabled? new_project.enable_ci settings = @project.gitlab_ci_project.attributes.select do |attr_name, value| diff --git a/app/services/system_hooks_service.rb b/app/services/system_hooks_service.rb index 9a5fe4af9dd..8b5143e1eb7 100644 --- a/app/services/system_hooks_service.rb +++ b/app/services/system_hooks_service.rb @@ -33,17 +33,7 @@ class SystemHooksService ) end when Project - owner = model.owner - - data.merge!({ - name: model.name, - path: model.path, - path_with_namespace: model.path_with_namespace, - project_id: model.id, - owner_name: owner.name, - owner_email: owner.respond_to?(:email) ? owner.email : "", - project_visibility: Project.visibility_levels.key(model.visibility_level_field).downcase - }) + data.merge!(project_data(model)) when User data.merge!({ name: model.name, @@ -51,16 +41,7 @@ class SystemHooksService user_id: model.id }) when ProjectMember - data.merge!({ - project_name: model.project.name, - project_path: model.project.path, - project_path_with_namespace: model.project.path_with_namespace, - project_id: model.project.id, - user_name: model.user.name, - user_email: model.user.email, - access_level: model.human_access, - project_visibility: Project.visibility_levels.key(model.project.visibility_level_field).downcase - }) + data.merge!(project_member_data(model)) when Group owner = model.owner @@ -72,15 +53,7 @@ class SystemHooksService owner_email: owner.respond_to?(:email) ? owner.email : nil, ) when GroupMember - data.merge!( - group_name: model.group.name, - group_path: model.group.path, - group_id: model.group.id, - user_name: model.user.name, - user_email: model.user.email, - user_id: model.user.id, - group_access: model.human_access, - ) + data.merge!(group_member_data(model)) end end @@ -96,4 +69,43 @@ class SystemHooksService "#{model.class.name.downcase}_#{event.to_s}" end end + + def project_data(model) + owner = model.owner + + { + name: model.name, + path: model.path, + path_with_namespace: model.path_with_namespace, + project_id: model.id, + owner_name: owner.name, + owner_email: owner.respond_to?(:email) ? owner.email : "", + project_visibility: Project.visibility_levels.key(model.visibility_level_field).downcase + } + end + + def project_member_data(model) + { + project_name: model.project.name, + project_path: model.project.path, + project_path_with_namespace: model.project.path_with_namespace, + project_id: model.project.id, + user_name: model.user.name, + user_email: model.user.email, + access_level: model.human_access, + project_visibility: Project.visibility_levels.key(model.project.visibility_level_field).downcase + } + end + + def group_member_data(model) + { + group_name: model.group.name, + group_path: model.group.path, + group_id: model.group.id, + user_name: model.user.name, + user_email: model.user.email, + user_id: model.user.id, + group_access: model.human_access, + } + end end diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index 708c2f00486..7e2bc834176 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -341,4 +341,22 @@ class SystemNoteService "* #{commit_ids} - #{commits_text} from branch `#{branch}`\n" end + + # Called when the status of a Task has changed + # + # noteable - Noteable object. + # project - Project owning noteable + # author - User performing the change + # new_task - TaskList::Item object. + # + # Example Note text: + # + # "Soandso marked the task Whatever as completed." + # + # Returns the created Note object + def self.change_task_status(noteable, project, author, new_task) + status_label = new_task.complete? ? Taskable::COMPLETED : Taskable::INCOMPLETE + body = "Marked the task **#{new_task.source}** as #{status_label}" + create_note(noteable: noteable, project: project, author: author, note: body) + end end diff --git a/app/services/update_release_service.rb b/app/services/update_release_service.rb new file mode 100644 index 00000000000..25eb13ef09a --- /dev/null +++ b/app/services/update_release_service.rb @@ -0,0 +1,29 @@ +require_relative 'base_service' + +class UpdateReleaseService < BaseService + def execute(tag_name, release_description) + + repository = project.repository + existing_tag = repository.find_tag(tag_name) + + if existing_tag + release = project.releases.find_by(tag: tag_name) + + if release + release.update_attributes(description: release_description) + + success(release) + else + error('Release does not exist', 404) + end + else + error('Tag does not exist', 404) + end + end + + def success(release) + out = super() + out[:release] = release + out + end +end |