diff --git a/app/controllers/concerns/service_params.rb b/app/controllers/concerns/service_params.rb index 2992568ae66..a8c0937569c 100644 --- a/app/controllers/concerns/service_params.rb +++ b/app/controllers/concerns/service_params.rb @@ -37,7 +37,6 @@ module ServiceParams :namespace, :new_issue_url, :notify, - :notify_only_broken_builds, :notify_only_broken_pipelines, :password, :priority, diff --git a/app/mailers/emails/builds.rb b/app/mailers/emails/builds.rb deleted file mode 100644 index 3853af6201a..00000000000 --- a/app/mailers/emails/builds.rb +++ /dev/null @@ -1,30 +0,0 @@ -module Emails - module Builds - def build_fail_email(build_id, to) - @build = Ci::Build.find(build_id) - @project = @build.project - - add_project_headers - add_build_headers('failed') - - mail(to: to, subject: subject("Build failed for #{@project.name}", @build.short_sha)) - end - - def build_success_email(build_id, to) - @build = Ci::Build.find(build_id) - @project = @build.project - - add_project_headers - add_build_headers('success') - mail(to: to, subject: subject("Build success for #{@project.name}", @build.short_sha)) - end - - private - - def add_build_headers(status) - headers['X-GitLab-Build-Id'] = @build.id - headers['X-GitLab-Build-Ref'] = @build.ref - headers['X-GitLab-Build-Status'] = status.to_s - end - end -end diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb index 5b9226a6b81..14df6f8f0a3 100644 --- a/app/mailers/notify.rb +++ b/app/mailers/notify.rb @@ -6,7 +6,6 @@ class Notify < BaseMailer include Emails::Notes include Emails::Projects include Emails::Profile - include Emails::Builds include Emails::Pipelines include Emails::Members diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 3722047251d..53fc0d87823 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -15,7 +15,7 @@ module Ci def persisted_environment @persisted_environment ||= Environment.find_by( name: expanded_environment_name, - project_id: gl_project_id + project: project ) end @@ -223,7 +223,8 @@ module Ci def merge_request merge_requests = MergeRequest.includes(:merge_request_diff) - .where(source_branch: ref, source_project_id: pipeline.gl_project_id) + .where(source_branch: ref, + source_project: pipeline.project) .reorder(iid: :asc) merge_requests.find do |merge_request| @@ -231,10 +232,6 @@ module Ci end end - def project_id - gl_project_id - end - def repo_url auth = "gitlab-ci-token:#{ensure_token!}@" project.http_url_to_repo.sub(/^https?:\/\//) do |prefix| @@ -561,7 +558,7 @@ module Ci end def unscoped_project - @unscoped_project ||= Project.unscoped.find_by(id: gl_project_id) + @unscoped_project ||= Project.unscoped.find_by(id: project_id) end CI_REGISTRY_USER = 'gitlab-ci-token'.freeze diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index d1009f88549..f12be98c80c 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -5,9 +5,7 @@ module Ci include Importable include AfterCommitQueue - self.table_name = 'ci_commits' - - belongs_to :project, foreign_key: :gl_project_id + belongs_to :project belongs_to :user has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index edd21f984c8..487ba61bc9c 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -9,7 +9,7 @@ module Ci has_many :builds has_many :runner_projects, dependent: :destroy - has_many :projects, through: :runner_projects, foreign_key: :gl_project_id + has_many :projects, through: :runner_projects has_one :last_build, ->() { order('id DESC') }, class_name: 'Ci::Build' @@ -24,7 +24,7 @@ module Ci scope :owned_or_shared, ->(project_id) do joins('LEFT JOIN ci_runner_projects ON ci_runner_projects.runner_id = ci_runners.id') - .where("ci_runner_projects.gl_project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id) + .where("ci_runner_projects.project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id) end scope :assignable_for, ->(project) do diff --git a/app/models/ci/runner_project.rb b/app/models/ci/runner_project.rb index 234376a7e4c..5f01a0daae9 100644 --- a/app/models/ci/runner_project.rb +++ b/app/models/ci/runner_project.rb @@ -1,10 +1,10 @@ module Ci class RunnerProject < ActiveRecord::Base extend Ci::Model - - belongs_to :runner - belongs_to :project, foreign_key: :gl_project_id - validates :runner_id, uniqueness: { scope: :gl_project_id } + belongs_to :runner + belongs_to :project + + validates :runner_id, uniqueness: { scope: :project_id } end end diff --git a/app/models/ci/trigger.rb b/app/models/ci/trigger.rb index 90473d41c04..cba1d81a861 100644 --- a/app/models/ci/trigger.rb +++ b/app/models/ci/trigger.rb @@ -4,7 +4,7 @@ module Ci acts_as_paranoid - belongs_to :project, foreign_key: :gl_project_id + belongs_to :project belongs_to :owner, class_name: "User" has_many :trigger_requests, dependent: :destroy diff --git a/app/models/ci/variable.rb b/app/models/ci/variable.rb index 2c8698d8b5d..6c6586110c5 100644 --- a/app/models/ci/variable.rb +++ b/app/models/ci/variable.rb @@ -2,11 +2,11 @@ module Ci class Variable < ActiveRecord::Base extend Ci::Model - belongs_to :project, foreign_key: :gl_project_id + belongs_to :project validates :key, presence: true, - uniqueness: { scope: :gl_project_id }, + uniqueness: { scope: :project_id }, length: { maximum: 255 }, format: { with: /\A[a-zA-Z0-9_]+\z/, message: "can contain only letters, digits and '_'." } diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index 7e23e14794f..8c71267da65 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -5,7 +5,7 @@ class CommitStatus < ActiveRecord::Base self.table_name = 'ci_builds' - belongs_to :project, foreign_key: :gl_project_id + belongs_to :project belongs_to :pipeline, class_name: 'Ci::Pipeline', foreign_key: :commit_id belongs_to :user @@ -133,6 +133,12 @@ class CommitStatus < ActiveRecord::Base false end + # Added in 9.0 to keep backward compatibility for projects exported in 8.17 + # and prior. + def gl_project_id + 'dummy' + end + def detailed_status(current_user) Gitlab::Ci::Status::Factory .new(self, current_user) diff --git a/app/models/project.rb b/app/models/project.rb index 2ffaaac93f3..17cf8226bcc 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -89,7 +89,6 @@ class Project < ActiveRecord::Base has_one :campfire_service, dependent: :destroy has_one :drone_ci_service, dependent: :destroy has_one :emails_on_push_service, dependent: :destroy - has_one :builds_email_service, dependent: :destroy has_one :pipelines_email_service, dependent: :destroy has_one :irker_service, dependent: :destroy has_one :pivotaltracker_service, dependent: :destroy @@ -159,13 +158,13 @@ class Project < ActiveRecord::Base has_one :project_feature, dependent: :destroy has_one :statistics, class_name: 'ProjectStatistics', dependent: :delete - has_many :commit_statuses, dependent: :destroy, foreign_key: :gl_project_id - has_many :pipelines, dependent: :destroy, class_name: 'Ci::Pipeline', foreign_key: :gl_project_id - has_many :builds, class_name: 'Ci::Build', foreign_key: :gl_project_id # the builds are created from the commit_statuses - has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject', foreign_key: :gl_project_id + has_many :commit_statuses, dependent: :destroy + has_many :pipelines, dependent: :destroy, class_name: 'Ci::Pipeline' + has_many :builds, class_name: 'Ci::Build' # the builds are created from the commit_statuses + has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject' has_many :runners, through: :runner_projects, source: :runner, class_name: 'Ci::Runner' - has_many :variables, dependent: :destroy, class_name: 'Ci::Variable', foreign_key: :gl_project_id - has_many :triggers, dependent: :destroy, class_name: 'Ci::Trigger', foreign_key: :gl_project_id + has_many :variables, dependent: :destroy, class_name: 'Ci::Variable' + has_many :triggers, dependent: :destroy, class_name: 'Ci::Trigger' has_many :environments, dependent: :destroy has_many :deployments, dependent: :destroy diff --git a/app/models/project_services/builds_email_service.rb b/app/models/project_services/builds_email_service.rb index ebd21e37189..0c526b53d72 100644 --- a/app/models/project_services/builds_email_service.rb +++ b/app/models/project_services/builds_email_service.rb @@ -1,107 +1,11 @@ +# This class is to be removed with 9.1 +# We should also by then remove BuildsEmailService from database class BuildsEmailService < Service - prop_accessor :recipients - boolean_accessor :add_pusher - boolean_accessor :notify_only_broken_builds - validates :recipients, presence: true, if: ->(s) { s.activated? && !s.add_pusher? } - - def initialize_properties - if properties.nil? - self.properties = {} - self.notify_only_broken_builds = true - end - end - - def title - 'Builds emails' - end - - def description - 'Email the builds status to a list of recipients.' - end - def self.to_param 'builds_email' end def self.supported_events - %w(build) - end - - def execute(push_data) - return unless supported_events.include?(push_data[:object_kind]) - return unless should_build_be_notified?(push_data) - - recipients = all_recipients(push_data) - - if recipients.any? - BuildEmailWorker.perform_async( - push_data[:build_id], - recipients, - push_data - ) - end - end - - def can_test? - project.builds.any? - end - - def disabled_title - "Please setup a build on your repository." - end - - def test_data(project = nil, user = nil) - Gitlab::DataBuilder::Build.build(project.builds.last) - end - - def fields - [ - { type: 'textarea', name: 'recipients', placeholder: 'Emails separated by comma' }, - { type: 'checkbox', name: 'add_pusher', label: 'Add pusher to recipients list' }, - { type: 'checkbox', name: 'notify_only_broken_builds' }, - ] - end - - def test(data) - begin - # bypass build status verification when testing - data[:build_status] = "failed" - data[:build_allow_failure] = false - - result = execute(data) - rescue StandardError => error - return { success: false, result: error } - end - - { success: true, result: result } - end - - def should_build_be_notified?(data) - case data[:build_status] - when 'success' - !notify_only_broken_builds? - when 'failed' - !allow_failure?(data) - else - false - end - end - - def allow_failure?(data) - data[:build_allow_failure] == true - end - - def all_recipients(data) - all_recipients = [] - - unless recipients.blank? - all_recipients += recipients.split(',').compact.reject(&:blank?) - end - - if add_pusher? && data[:user][:email] - all_recipients << data[:user][:email] - end - - all_recipients + %w[] end end diff --git a/app/models/project_services/chat_message/build_message.rb b/app/models/project_services/chat_message/build_message.rb deleted file mode 100644 index c776e0a20c4..00000000000 --- a/app/models/project_services/chat_message/build_message.rb +++ /dev/null @@ -1,102 +0,0 @@ -module ChatMessage - class BuildMessage < BaseMessage - attr_reader :sha - attr_reader :ref_type - attr_reader :ref - attr_reader :status - attr_reader :project_name - attr_reader :project_url - attr_reader :user_name - attr_reader :user_url - attr_reader :duration - attr_reader :stage - attr_reader :build_id - attr_reader :build_name - - def initialize(params) - @sha = params[:sha] - @ref_type = params[:tag] ? 'tag' : 'branch' - @ref = params[:ref] - @project_name = params[:project_name] - @project_url = params[:project_url] - @status = params[:commit][:status] - @user_name = params[:commit][:author_name] - @user_url = params[:commit][:author_url] - @duration = params[:commit][:duration] - @stage = params[:build_stage] - @build_name = params[:build_name] - @build_id = params[:build_id] - end - - def pretext - '' - end - - def fallback - format(message) - end - - def attachments - [{ text: format(message), color: attachment_color }] - end - - private - - def message - "#{project_link}: Commit #{commit_link} of #{branch_link} #{ref_type} by #{user_link} #{humanized_status} on build #{build_link} of stage #{stage} in #{duration} #{'second'.pluralize(duration)}" - end - - def build_url - "#{project_url}/builds/#{build_id}" - end - - def build_link - link(build_name, build_url) - end - - def user_link - link(user_name, user_url) - end - - def format(string) - Slack::Notifier::LinkFormatter.format(string) - end - - def humanized_status - case status - when 'success' - 'passed' - else - status - end - end - - def attachment_color - if status == 'success' - 'good' - else - 'danger' - end - end - - def branch_url - "#{project_url}/commits/#{ref}" - end - - def branch_link - link(ref, branch_url) - end - - def project_link - link(project_name, project_url) - end - - def commit_url - "#{project_url}/commit/#{sha}/builds" - end - - def commit_link - link(Commit.truncate_sha(sha), commit_url) - end - end -end diff --git a/app/models/project_services/chat_notification_service.rb b/app/models/project_services/chat_notification_service.rb index 8468934425f..200be99f36b 100644 --- a/app/models/project_services/chat_notification_service.rb +++ b/app/models/project_services/chat_notification_service.rb @@ -6,7 +6,7 @@ class ChatNotificationService < Service default_value_for :category, 'chat' prop_accessor :webhook, :username, :channel - boolean_accessor :notify_only_broken_builds, :notify_only_broken_pipelines + boolean_accessor :notify_only_broken_pipelines validates :webhook, presence: true, url: true, if: :activated? @@ -16,7 +16,6 @@ class ChatNotificationService < Service if properties.nil? self.properties = {} - self.notify_only_broken_builds = true self.notify_only_broken_pipelines = true end end @@ -27,7 +26,7 @@ class ChatNotificationService < Service def self.supported_events %w[push issue confidential_issue merge_request note tag_push - build pipeline wiki_page] + pipeline wiki_page] end def execute(data) @@ -89,8 +88,6 @@ class ChatNotificationService < Service ChatMessage::MergeMessage.new(data) unless is_update?(data) when "note" ChatMessage::NoteMessage.new(data) - when "build" - ChatMessage::BuildMessage.new(data) if should_build_be_notified?(data) when "pipeline" ChatMessage::PipelineMessage.new(data) if should_pipeline_be_notified?(data) when "wiki_page" @@ -125,17 +122,6 @@ class ChatNotificationService < Service data[:object_attributes][:action] == 'update' end - def should_build_be_notified?(data) - case data[:commit][:status] - when 'success' - !notify_only_broken_builds? - when 'failed' - true - else - false - end - end - def should_pipeline_be_notified?(data) case data[:object_attributes][:status] when 'success' diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index c4142c38b2f..8b181221bb0 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -9,13 +9,13 @@ class HipchatService < Service ].freeze prop_accessor :token, :room, :server, :color, :api_version - boolean_accessor :notify_only_broken_builds, :notify + boolean_accessor :notify_only_broken_pipelines, :notify validates :token, presence: true, if: :activated? def initialize_properties if properties.nil? self.properties = {} - self.notify_only_broken_builds = true + self.notify_only_broken_pipelines = true end end @@ -41,12 +41,12 @@ class HipchatService < Service placeholder: 'Leave blank for default (v2)' }, { type: 'text', name: 'server', placeholder: 'Leave blank for default. https://hipchat.example.com' }, - { type: 'checkbox', name: 'notify_only_broken_builds' }, + { type: 'checkbox', name: 'notify_only_broken_pipelines' }, ] end def self.supported_events - %w(push issue confidential_issue merge_request note tag_push build) + %w(push issue confidential_issue merge_request note tag_push pipeline) end def execute(data) @@ -90,8 +90,8 @@ class HipchatService < Service create_merge_request_message(data) unless is_update?(data) when "note" create_note_message(data) - when "build" - create_build_message(data) if should_build_be_notified?(data) + when "pipeline" + create_pipeline_message(data) if should_pipeline_be_notified?(data) end end @@ -240,28 +240,29 @@ class HipchatService < Service message end - def create_build_message(data) - ref_type = data[:tag] ? 'tag' : 'branch' - ref = data[:ref] - sha = data[:sha] - user_name = data[:commit][:author_name] - status = data[:commit][:status] - duration = data[:commit][:duration] + def create_pipeline_message(data) + pipeline_attributes = data[:object_attributes] + pipeline_id = pipeline_attributes[:id] + ref_type = pipeline_attributes[:tag] ? 'tag' : 'branch' + ref = pipeline_attributes[:ref] + user_name = (data[:user] && data[:user][:name]) || 'API' + status = pipeline_attributes[:status] + duration = pipeline_attributes[:duration] branch_link = "#{ref}" - commit_link = "#{Commit.truncate_sha(sha)}" + pipeline_url = "##{pipeline_id}" - "#{project_link}: Commit #{commit_link} of #{branch_link} #{ref_type} by #{user_name} #{humanized_status(status)} in #{duration} second(s)" + "#{project_link}: Pipeline #{pipeline_url} of #{branch_link} #{ref_type} by #{user_name} #{humanized_status(status)} in #{duration} second(s)" end def message_color(data) - build_status_color(data) || color || 'yellow' + pipeline_status_color(data) || color || 'yellow' end - def build_status_color(data) - return unless data && data[:object_kind] == 'build' + def pipeline_status_color(data) + return unless data && data[:object_kind] == 'pipeline' - case data[:commit][:status] + case data[:object_attributes][:status] when 'success' 'green' else @@ -294,10 +295,10 @@ class HipchatService < Service end end - def should_build_be_notified?(data) - case data[:commit][:status] + def should_pipeline_be_notified?(data) + case data[:object_attributes][:status] when 'success' - !notify_only_broken_builds? + !notify_only_broken_pipelines? when 'failed' true else diff --git a/app/models/project_services/mattermost_service.rb b/app/models/project_services/mattermost_service.rb index c13538e9fea..1156d050622 100644 --- a/app/models/project_services/mattermost_service.rb +++ b/app/models/project_services/mattermost_service.rb @@ -30,7 +30,6 @@ class MattermostService < ChatNotificationService [ { type: 'text', name: 'webhook', placeholder: 'e.g. http://mattermost_host/hooks/…' }, { type: 'text', name: 'username', placeholder: 'e.g. GitLab' }, - { type: 'checkbox', name: 'notify_only_broken_builds' }, { type: 'checkbox', name: 'notify_only_broken_pipelines' }, ] end diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb index da7496573ef..b657db6f9ee 100644 --- a/app/models/project_services/slack_service.rb +++ b/app/models/project_services/slack_service.rb @@ -29,7 +29,6 @@ class SlackService < ChatNotificationService [ { type: 'text', name: 'webhook', placeholder: 'e.g. https://hooks.slack.com/services/…' }, { type: 'text', name: 'username', placeholder: 'e.g. GitLab' }, - { type: 'checkbox', name: 'notify_only_broken_builds' }, { type: 'checkbox', name: 'notify_only_broken_pipelines' }, ] end diff --git a/app/models/service.rb b/app/models/service.rb index 2f75a2e4e7f..e73f7e5d1a3 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -215,7 +215,6 @@ class Service < ActiveRecord::Base assembla bamboo buildkite - builds_email bugzilla campfire custom_issue_tracker diff --git a/app/models/user.rb b/app/models/user.rb index 39c1281179b..8c7ad5d5174 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -877,7 +877,7 @@ class User < ActiveRecord::Base def ci_authorized_runners @ci_authorized_runners ||= begin runner_ids = Ci::RunnerProject. - where("ci_runner_projects.gl_project_id IN (#{ci_projects_union.to_sql})"). + where("ci_runner_projects.project_id IN (#{ci_projects_union.to_sql})"). select(:runner_id) Ci::Runner.specific.where(id: runner_ids) end diff --git a/app/services/ci/register_job_service.rb b/app/services/ci/register_job_service.rb index 0ab9042bf24..d6a4280ce4c 100644 --- a/app/services/ci/register_job_service.rb +++ b/app/services/ci/register_job_service.rb @@ -55,13 +55,13 @@ module Ci new_builds. # don't run projects which have not enabled shared runners and builds joins(:project).where(projects: { shared_runners_enabled: true }). - joins('LEFT JOIN project_features ON ci_builds.gl_project_id = project_features.project_id'). + joins('LEFT JOIN project_features ON ci_builds.project_id = project_features.project_id'). where('project_features.builds_access_level IS NULL or project_features.builds_access_level > 0'). # Implement fair scheduling # this returns builds that are ordered by number of running builds # we prefer projects that don't use shared runners at all - joins("LEFT JOIN (#{running_builds_for_shared_runners.to_sql}) AS project_builds ON ci_builds.gl_project_id=project_builds.gl_project_id"). + joins("LEFT JOIN (#{running_builds_for_shared_runners.to_sql}) AS project_builds ON ci_builds.project_id=project_builds.project_id"). order('COALESCE(project_builds.running_builds, 0) ASC', 'ci_builds.id ASC') end @@ -71,7 +71,7 @@ module Ci def running_builds_for_shared_runners Ci::Build.running.where(runner: Ci::Runner.shared). - group(:gl_project_id).select(:gl_project_id, 'count(*) AS running_builds') + group(:project_id).select(:project_id, 'count(*) AS running_builds') end def new_builds diff --git a/app/views/notify/build_fail_email.html.haml b/app/views/notify/build_fail_email.html.haml deleted file mode 100644 index 060b50ffc69..00000000000 --- a/app/views/notify/build_fail_email.html.haml +++ /dev/null @@ -1,24 +0,0 @@ -- content_for :header do - %h1{ style: "background: #c40834; color: #FFF; font: normal 20px Helvetica, Arial, sans-serif; margin: 0; padding: 5px 10px; line-height: 32px; font-size: 16px;" } - GitLab (job failed) - -%h3 - Project: - = link_to namespace_project_url(@project.namespace, @project) do - = @project.name - -%p - Commit: #{link_to @build.short_sha, namespace_project_commit_url(@build.project.namespace, @build.project, @build.sha)} -%p - Author: #{@build.pipeline.git_author_name} -%p - Branch: #{@build.ref} -%p - Stage: #{@build.stage} -%p - Job: #{@build.name} -%p - Message: #{@build.pipeline.git_commit_message} - -%p - Job details: #{link_to "Job #{@build.id}", namespace_project_build_url(@build.project.namespace, @build.project, @build)} diff --git a/app/views/notify/build_fail_email.text.erb b/app/views/notify/build_fail_email.text.erb deleted file mode 100644 index 2a94688a6b0..00000000000 --- a/app/views/notify/build_fail_email.text.erb +++ /dev/null @@ -1,11 +0,0 @@ -Job failed for <%= @project.name %> - -Status: <%= @build.status %> -Commit: <%= @build.pipeline.short_sha %> -Author: <%= @build.pipeline.git_author_name %> -Branch: <%= @build.ref %> -Stage: <%= @build.stage %> -Job: <%= @build.name %> -Message: <%= @build.pipeline.git_commit_message %> - -Url: <%= namespace_project_build_url(@build.project.namespace, @build.project, @build) %> diff --git a/app/views/notify/build_success_email.html.haml b/app/views/notify/build_success_email.html.haml deleted file mode 100644 index ca0eaa96a9d..00000000000 --- a/app/views/notify/build_success_email.html.haml +++ /dev/null @@ -1,24 +0,0 @@ -- content_for :header do - %h1{ style: "background: #38CF5B; color: #FFF; font: normal 20px Helvetica, Arial, sans-serif; margin: 0; padding: 5px 10px; line-height: 32px; font-size: 16px;" } - GitLab (job successful) - -%h3 - Project: - = link_to namespace_project_url(@project.namespace, @project) do - = @project.name - -%p - Commit: #{link_to @build.short_sha, namespace_project_commit_url(@build.project.namespace, @build.project, @build.sha)} -%p - Author: #{@build.pipeline.git_author_name} -%p - Branch: #{@build.ref} -%p - Stage: #{@build.stage} -%p - Job: #{@build.name} -%p - Message: #{@build.pipeline.git_commit_message} - -%p - Job details: #{link_to "Job #{@build.id}", namespace_project_build_url(@build.project.namespace, @build.project, @build)} diff --git a/app/views/notify/build_success_email.text.erb b/app/views/notify/build_success_email.text.erb deleted file mode 100644 index 445cd46e64f..00000000000 --- a/app/views/notify/build_success_email.text.erb +++ /dev/null @@ -1,11 +0,0 @@ -Job successful for <%= @project.name %> - -Status: <%= @build.status %> -Commit: <%= @build.pipeline.short_sha %> -Author: <%= @build.pipeline.git_author_name %> -Branch: <%= @build.ref %> -Stage: <%= @build.stage %> -Job: <%= @build.name %> -Message: <%= @build.pipeline.git_commit_message %> - -Url: <%= namespace_project_build_url(@build.project.namespace, @build.project, @build) %> diff --git a/app/workers/build_email_worker.rb b/app/workers/build_email_worker.rb deleted file mode 100644 index 5fdb1f2baa0..00000000000 --- a/app/workers/build_email_worker.rb +++ /dev/null @@ -1,20 +0,0 @@ -class BuildEmailWorker - include Sidekiq::Worker - include BuildQueue - - def perform(build_id, recipients, push_data) - recipients.each do |recipient| - begin - case push_data['build_status'] - when 'success' - Notify.build_success_email(build_id, recipient).deliver_now - when 'failed' - Notify.build_fail_email(build_id, recipient).deliver_now - end - # These are input errors and won't be corrected even if Sidekiq retries - rescue Net::SMTPFatalError, Net::SMTPSyntaxError => e - logger.info("Failed to send e-mail for project '#{push_data['project_name']}' to #{recipient}: #{e}") - end - end - end -end diff --git a/changelogs/unreleased/23993-drop-ci_projects.yml b/changelogs/unreleased/23993-drop-ci_projects.yml new file mode 100644 index 00000000000..ee9cf774e37 --- /dev/null +++ b/changelogs/unreleased/23993-drop-ci_projects.yml @@ -0,0 +1,6 @@ +--- +title: Drop unused ci_projects table and some unused project_id columns, + then rename gl_project_id to project_id. Stop exporting job trace when + exporting projects. +merge_request: 9378 +author: David Wagner diff --git a/changelogs/unreleased/migrate-pipeline-events-and-email-service.yml b/changelogs/unreleased/migrate-pipeline-events-and-email-service.yml new file mode 100644 index 00000000000..ce4d5092c17 --- /dev/null +++ b/changelogs/unreleased/migrate-pipeline-events-and-email-service.yml @@ -0,0 +1,4 @@ +--- +title: Migrate SlackService and MattermostService from build_events to pipeline_events, and migrate BuildsEmailService to PipelinesEmailService. Update Hipchat to use pipeline events rather than build events. +merge_request: 8196 +author: diff --git a/changelogs/unreleased/remove-unused-ci-tables.yml b/changelogs/unreleased/remove-unused-ci-tables.yml new file mode 100644 index 00000000000..fccfb882bd9 --- /dev/null +++ b/changelogs/unreleased/remove-unused-ci-tables.yml @@ -0,0 +1,4 @@ +--- +title: Remove various unused CI tables and columns +merge_request: 9639 +author: diff --git a/changelogs/unreleased/rename-ci_commits-to-ci_pipeline.yml b/changelogs/unreleased/rename-ci_commits-to-ci_pipeline.yml new file mode 100644 index 00000000000..4067b3de00c --- /dev/null +++ b/changelogs/unreleased/rename-ci_commits-to-ci_pipeline.yml @@ -0,0 +1,4 @@ +--- +title: Rename table ci_commits to ci_pipelines +merge_request: 9638 +author: diff --git a/db/migrate/20170216135621_add_index_for_latest_successful_pipeline.rb b/db/migrate/20170216135621_add_index_for_latest_successful_pipeline.rb index 65adc90c2c1..8a96a784c97 100644 --- a/db/migrate/20170216135621_add_index_for_latest_successful_pipeline.rb +++ b/db/migrate/20170216135621_add_index_for_latest_successful_pipeline.rb @@ -5,7 +5,7 @@ class AddIndexForLatestSuccessfulPipeline < ActiveRecord::Migration disable_ddl_transaction! def up - add_concurrent_index :ci_commits, [:gl_project_id, :ref, :status] + add_concurrent_index(:ci_commits, [:gl_project_id, :ref, :status]) end def down diff --git a/db/migrate/20170222143317_drop_ci_projects.rb b/db/migrate/20170222143317_drop_ci_projects.rb new file mode 100644 index 00000000000..4db8658f36f --- /dev/null +++ b/db/migrate/20170222143317_drop_ci_projects.rb @@ -0,0 +1,34 @@ +class DropCiProjects < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def up + drop_table :ci_projects + end + + def down + create_table "ci_projects", force: :cascade do |t| + t.string "name" + t.integer "timeout", default: 3600, null: false + t.datetime "created_at" + t.datetime "updated_at" + t.string "token" + t.string "default_ref" + t.string "path" + t.boolean "always_build", default: false, null: false + t.integer "polling_interval" + t.boolean "public", default: false, null: false + t.string "ssh_url_to_repo" + t.integer "gitlab_id" + t.boolean "allow_git_fetch", default: true, null: false + t.string "email_recipients", default: "", null: false + t.boolean "email_add_pusher", default: true, null: false + t.boolean "email_only_broken_builds", default: true, null: false + t.string "skip_refs" + t.string "coverage_regex" + t.boolean "shared_runners_enabled", default: false + t.text "generated_yaml_config" + end + end +end diff --git a/db/migrate/20170222143500_remove_old_project_id_columns.rb b/db/migrate/20170222143500_remove_old_project_id_columns.rb new file mode 100644 index 00000000000..eac93e8e407 --- /dev/null +++ b/db/migrate/20170222143500_remove_old_project_id_columns.rb @@ -0,0 +1,28 @@ +class RemoveOldProjectIdColumns < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + disable_ddl_transaction! + + DOWNTIME = true + DOWNTIME_REASON = 'Unused columns are being removed.' + + def up + remove_index :ci_builds, :project_id if + index_exists?(:ci_builds, :project_id) + + remove_column :ci_builds, :project_id + remove_column :ci_commits, :project_id + remove_column :ci_runner_projects, :project_id + remove_column :ci_triggers, :project_id + remove_column :ci_variables, :project_id + end + + def down + add_column :ci_builds, :project_id, :integer + add_column :ci_commits, :project_id, :integer + add_column :ci_runner_projects, :project_id, :integer + add_column :ci_triggers, :project_id, :integer + add_column :ci_variables, :project_id, :integer + + add_concurrent_index :ci_builds, :project_id + end +end diff --git a/db/migrate/20170222143603_rename_gl_project_id_to_project_id.rb b/db/migrate/20170222143603_rename_gl_project_id_to_project_id.rb new file mode 100644 index 00000000000..7c19d471557 --- /dev/null +++ b/db/migrate/20170222143603_rename_gl_project_id_to_project_id.rb @@ -0,0 +1,14 @@ +class RenameGlProjectIdToProjectId < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = true + DOWNTIME_REASON = 'Renaming an actively used column.' + + def change + rename_column :ci_builds, :gl_project_id, :project_id + rename_column :ci_commits, :gl_project_id, :project_id + rename_column :ci_runner_projects, :gl_project_id, :project_id + rename_column :ci_triggers, :gl_project_id, :project_id + rename_column :ci_variables, :gl_project_id, :project_id + end +end diff --git a/db/migrate/20170301195939_rename_ci_commits_to_ci_pipelines.rb b/db/migrate/20170301195939_rename_ci_commits_to_ci_pipelines.rb new file mode 100644 index 00000000000..4f061d96392 --- /dev/null +++ b/db/migrate/20170301195939_rename_ci_commits_to_ci_pipelines.rb @@ -0,0 +1,10 @@ +class RenameCiCommitsToCiPipelines < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = true + DOWNTIME_REASON = 'Rename table ci_commits to ci_pipelines' + + def change + rename_table 'ci_commits', 'ci_pipelines' + end +end diff --git a/db/migrate/20170301205639_remove_unused_ci_tables_and_columns.rb b/db/migrate/20170301205639_remove_unused_ci_tables_and_columns.rb new file mode 100644 index 00000000000..1e2abea5254 --- /dev/null +++ b/db/migrate/20170301205639_remove_unused_ci_tables_and_columns.rb @@ -0,0 +1,83 @@ +class RemoveUnusedCiTablesAndColumns < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = true + DOWNTIME_REASON = + 'Remove unused columns in used tables.' \ + ' Downtime required in case Rails caches them' + + def up + %w[ci_application_settings + ci_events + ci_jobs + ci_sessions + ci_taggings + ci_tags].each do |table| + drop_table(table) + end + + remove_column :ci_pipelines, :push_data, :text + remove_column :ci_builds, :job_id, :integer + remove_column :ci_builds, :deploy, :boolean + end + + def down + add_column :ci_builds, :deploy, :boolean + add_column :ci_builds, :job_id, :integer + add_column :ci_pipelines, :push_data, :text + + create_table "ci_tags", force: :cascade do |t| + t.string "name" + t.integer "taggings_count", default: 0 + end + + create_table "ci_taggings", force: :cascade do |t| + t.integer "tag_id" + t.integer "taggable_id" + t.string "taggable_type" + t.integer "tagger_id" + t.string "tagger_type" + t.string "context", limit: 128 + t.datetime "created_at" + end + + add_index "ci_taggings", %w[taggable_id taggable_type context] + + create_table "ci_sessions", force: :cascade do |t| + t.string "session_id", null: false + t.text "data" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "ci_jobs", force: :cascade do |t| + t.integer "project_id", null: false + t.text "commands" + t.boolean "active", default: true, null: false + t.datetime "created_at" + t.datetime "updated_at" + t.string "name" + t.boolean "build_branches", default: true, null: false + t.boolean "build_tags", default: false, null: false + t.string "job_type", default: "parallel" + t.string "refs" + t.datetime "deleted_at" + end + + create_table "ci_events", force: :cascade do |t| + t.integer "project_id" + t.integer "user_id" + t.integer "is_admin" + t.text "description" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "ci_application_settings", force: :cascade do |t| + t.boolean "all_broken_builds" + t.boolean "add_pusher" + t.datetime "created_at" + t.datetime "updated_at" + end + end +end diff --git a/db/post_migrate/20170301205640_migrate_build_events_to_pipeline_events.rb b/db/post_migrate/20170301205640_migrate_build_events_to_pipeline_events.rb new file mode 100644 index 00000000000..2dd14ee5a78 --- /dev/null +++ b/db/post_migrate/20170301205640_migrate_build_events_to_pipeline_events.rb @@ -0,0 +1,87 @@ +class MigrateBuildEventsToPipelineEvents < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + include Gitlab::Database + + DOWNTIME = false + + def up + Gitlab::Database.with_connection_pool(2) do |pool| + threads = [] + + threads << Thread.new do + pool.with_connection do |connection| + Thread.current[:foreign_key_connection] = connection + + execute(<<-SQL.strip_heredoc) + UPDATE services + SET properties = replace(properties, + 'notify_only_broken_builds', + 'notify_only_broken_pipelines') + , pipeline_events = #{true_value} + , build_events = #{false_value} + WHERE type IN + ('SlackService', 'MattermostService', 'HipchatService') + AND build_events = #{true_value}; + SQL + end + end + + threads << Thread.new do + pool.with_connection do |connection| + Thread.current[:foreign_key_connection] = connection + + execute(update_pipeline_services_sql) + end + end + + threads.each(&:join) + end + end + + def down + # Don't bother to migrate the data back + end + + def connection + # Rails memoizes connection objects, but this causes them to be shared + # amongst threads; we don't want that. + Thread.current[:foreign_key_connection] || ActiveRecord::Base.connection + end + + private + + def update_pipeline_services_sql + if Gitlab::Database.postgresql? + <<-SQL + UPDATE services + SET type = 'PipelinesEmailService' + , properties = replace(properties, + 'notify_only_broken_builds', + 'notify_only_broken_pipelines') + , pipeline_events = #{true_value} + , build_events = #{false_value} + WHERE type = 'BuildsEmailService' + AND + (SELECT 1 FROM services pipeline_services + WHERE pipeline_services.project_id = services.project_id + AND pipeline_services.type = 'PipelinesEmailService' LIMIT 1) + IS NULL; + SQL + else + <<-SQL + UPDATE services build_services + LEFT OUTER JOIN services pipeline_services + ON build_services.project_id = pipeline_services.project_id + AND pipeline_services.type = 'PipelinesEmailService' + SET build_services.type = 'PipelinesEmailService' + , build_services.properties = replace(build_services.properties, + 'notify_only_broken_builds', + 'notify_only_broken_pipelines') + , build_services.pipeline_events = #{true_value} + , build_services.build_events = #{false_value} + WHERE build_services.type = 'BuildsEmailService' + AND pipeline_services.id IS NULL; + SQL + end.strip_heredoc + end +end diff --git a/db/schema.rb b/db/schema.rb index 6eb3c95de93..634d02bb5bc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -185,15 +185,7 @@ ActiveRecord::Schema.define(version: 20170315174634) do add_index "chat_teams", ["namespace_id"], name: "index_chat_teams_on_namespace_id", unique: true, using: :btree - create_table "ci_application_settings", force: :cascade do |t| - t.boolean "all_broken_builds" - t.boolean "add_pusher" - t.datetime "created_at" - t.datetime "updated_at" - end - create_table "ci_builds", force: :cascade do |t| - t.integer "project_id" t.string "status" t.datetime "finished_at" t.text "trace" @@ -204,9 +196,7 @@ ActiveRecord::Schema.define(version: 20170315174634) do t.float "coverage" t.integer "commit_id" t.text "commands" - t.integer "job_id" t.string "name" - t.boolean "deploy", default: false t.text "options" t.boolean "allow_failure", default: false, null: false t.string "stage" @@ -219,7 +209,7 @@ ActiveRecord::Schema.define(version: 20170315174634) do t.string "target_url" t.string "description" t.text "artifacts_file" - t.integer "gl_project_id" + t.integer "project_id" t.text "artifacts_metadata" t.integer "erased_by_id" t.datetime "erased_at" @@ -238,25 +228,22 @@ ActiveRecord::Schema.define(version: 20170315174634) do add_index "ci_builds", ["commit_id", "status", "type"], name: "index_ci_builds_on_commit_id_and_status_and_type", using: :btree add_index "ci_builds", ["commit_id", "type", "name", "ref"], name: "index_ci_builds_on_commit_id_and_type_and_name_and_ref", using: :btree add_index "ci_builds", ["commit_id", "type", "ref"], name: "index_ci_builds_on_commit_id_and_type_and_ref", using: :btree - add_index "ci_builds", ["gl_project_id"], name: "index_ci_builds_on_gl_project_id", using: :btree add_index "ci_builds", ["project_id"], name: "index_ci_builds_on_project_id", using: :btree add_index "ci_builds", ["runner_id"], name: "index_ci_builds_on_runner_id", using: :btree add_index "ci_builds", ["status", "type", "runner_id"], name: "index_ci_builds_on_status_and_type_and_runner_id", using: :btree add_index "ci_builds", ["status"], name: "index_ci_builds_on_status", using: :btree add_index "ci_builds", ["token"], name: "index_ci_builds_on_token", unique: true, using: :btree - create_table "ci_commits", force: :cascade do |t| - t.integer "project_id" + create_table "ci_pipelines", force: :cascade do |t| t.string "ref" t.string "sha" t.string "before_sha" - t.text "push_data" t.datetime "created_at" t.datetime "updated_at" t.boolean "tag", default: false t.text "yaml_errors" t.datetime "committed_at" - t.integer "gl_project_id" + t.integer "project_id" t.string "status" t.datetime "started_at" t.datetime "finished_at" @@ -265,67 +252,20 @@ ActiveRecord::Schema.define(version: 20170315174634) do t.integer "lock_version" end - add_index "ci_commits", ["gl_project_id", "ref", "status"], name: "index_ci_commits_on_gl_project_id_and_ref_and_status", using: :btree - add_index "ci_commits", ["gl_project_id", "sha"], name: "index_ci_commits_on_gl_project_id_and_sha", using: :btree - add_index "ci_commits", ["gl_project_id"], name: "index_ci_commits_on_gl_project_id", using: :btree - add_index "ci_commits", ["status"], name: "index_ci_commits_on_status", using: :btree - add_index "ci_commits", ["user_id"], name: "index_ci_commits_on_user_id", using: :btree - - create_table "ci_events", force: :cascade do |t| - t.integer "project_id" - t.integer "user_id" - t.integer "is_admin" - t.text "description" - t.datetime "created_at" - t.datetime "updated_at" - end - - create_table "ci_jobs", force: :cascade do |t| - t.integer "project_id", null: false - t.text "commands" - t.boolean "active", default: true, null: false - t.datetime "created_at" - t.datetime "updated_at" - t.string "name" - t.boolean "build_branches", default: true, null: false - t.boolean "build_tags", default: false, null: false - t.string "job_type", default: "parallel" - t.string "refs" - t.datetime "deleted_at" - end - - create_table "ci_projects", force: :cascade do |t| - t.string "name" - t.integer "timeout", default: 3600, null: false - t.datetime "created_at" - t.datetime "updated_at" - t.string "token" - t.string "default_ref" - t.string "path" - t.boolean "always_build", default: false, null: false - t.integer "polling_interval" - t.boolean "public", default: false, null: false - t.string "ssh_url_to_repo" - t.integer "gitlab_id" - t.boolean "allow_git_fetch", default: true, null: false - t.string "email_recipients", default: "", null: false - t.boolean "email_add_pusher", default: true, null: false - t.boolean "email_only_broken_builds", default: true, null: false - t.string "skip_refs" - t.string "coverage_regex" - t.boolean "shared_runners_enabled", default: false - t.text "generated_yaml_config" - end + add_index "ci_pipelines", ["project_id", "ref", "status"], name: "index_ci_pipelines_on_project_id_and_ref_and_status", using: :btree + add_index "ci_pipelines", ["project_id", "sha"], name: "index_ci_pipelines_on_project_id_and_sha", using: :btree + add_index "ci_pipelines", ["project_id"], name: "index_ci_pipelines_on_project_id", using: :btree + add_index "ci_pipelines", ["status"], name: "index_ci_pipelines_on_status", using: :btree + add_index "ci_pipelines", ["user_id"], name: "index_ci_pipelines_on_user_id", using: :btree create_table "ci_runner_projects", force: :cascade do |t| t.integer "runner_id", null: false - t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.integer "gl_project_id" + t.integer "project_id" end - add_index "ci_runner_projects", ["gl_project_id"], name: "index_ci_runner_projects_on_gl_project_id", using: :btree + add_index "ci_runner_projects", ["project_id"], name: "index_ci_runner_projects_on_project_id", using: :btree add_index "ci_runner_projects", ["runner_id"], name: "index_ci_runner_projects_on_runner_id", using: :btree create_table "ci_runners", force: :cascade do |t| @@ -349,30 +289,6 @@ ActiveRecord::Schema.define(version: 20170315174634) do add_index "ci_runners", ["locked"], name: "index_ci_runners_on_locked", using: :btree add_index "ci_runners", ["token"], name: "index_ci_runners_on_token", using: :btree - create_table "ci_sessions", force: :cascade do |t| - t.string "session_id", null: false - t.text "data" - t.datetime "created_at" - t.datetime "updated_at" - end - - create_table "ci_taggings", force: :cascade do |t| - t.integer "tag_id" - t.integer "taggable_id" - t.string "taggable_type" - t.integer "tagger_id" - t.string "tagger_type" - t.string "context", limit: 128 - t.datetime "created_at" - end - - add_index "ci_taggings", ["taggable_id", "taggable_type", "context"], name: "index_ci_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree - - create_table "ci_tags", force: :cascade do |t| - t.string "name" - t.integer "taggings_count", default: 0 - end - create_table "ci_trigger_requests", force: :cascade do |t| t.integer "trigger_id", null: false t.text "variables" @@ -385,28 +301,26 @@ ActiveRecord::Schema.define(version: 20170315174634) do create_table "ci_triggers", force: :cascade do |t| t.string "token" - t.integer "project_id" t.datetime "deleted_at" t.datetime "created_at" t.datetime "updated_at" - t.integer "gl_project_id" + t.integer "project_id" t.integer "owner_id" t.string "description" end - add_index "ci_triggers", ["gl_project_id"], name: "index_ci_triggers_on_gl_project_id", using: :btree + add_index "ci_triggers", ["project_id"], name: "index_ci_triggers_on_project_id", using: :btree create_table "ci_variables", force: :cascade do |t| - t.integer "project_id" t.string "key" t.text "value" t.text "encrypted_value" t.string "encrypted_value_salt" t.string "encrypted_value_iv" - t.integer "gl_project_id" + t.integer "project_id" end - add_index "ci_variables", ["gl_project_id"], name: "index_ci_variables_on_gl_project_id", using: :btree + add_index "ci_variables", ["project_id"], name: "index_ci_variables_on_project_id", using: :btree create_table "deploy_keys_projects", force: :cascade do |t| t.integer "deploy_key_id", null: false @@ -1378,7 +1292,7 @@ ActiveRecord::Schema.define(version: 20170315174634) do add_foreign_key "labels", "namespaces", column: "group_id", on_delete: :cascade add_foreign_key "lists", "boards" add_foreign_key "lists", "labels" - add_foreign_key "merge_request_metrics", "ci_commits", column: "pipeline_id", on_delete: :cascade + add_foreign_key "merge_request_metrics", "ci_pipelines", column: "pipeline_id", on_delete: :cascade add_foreign_key "merge_request_metrics", "merge_requests", on_delete: :cascade add_foreign_key "merge_requests_closing_issues", "issues", on_delete: :cascade add_foreign_key "merge_requests_closing_issues", "merge_requests", on_delete: :cascade diff --git a/doc/api/services.md b/doc/api/services.md index 8e7afe41b0c..7d4779f1137 100644 --- a/doc/api/services.md +++ b/doc/api/services.md @@ -139,43 +139,6 @@ Get Buildkite service settings for a project. GET /projects/:id/services/buildkite ``` -## Build-Emails - -Get emails for GitLab CI builds. - -### Create/Edit Build-Emails service - -Set Build-Emails service for a project. - -``` -PUT /projects/:id/services/jobs-email -``` - -Parameters: - -| Attribute | Type | Required | Description | -| --------- | ---- | -------- | ----------- | -| `recipients` | string | yes | Comma-separated list of recipient email addresses | -| `add_pusher` | boolean | no | Add pusher to recipients list | -| `notify_only_broken_jobs` | boolean | no | Notify only broken jobs | - - -### Delete Job-Emails service - -Delete Build-Emails service for a project. - -``` -DELETE /projects/:id/services/jobs-email -``` - -### Get Job-Emails service settings - -Get Build-Emails service settings for a project. - -``` -GET /projects/:id/services/jobs-email -``` - ## Campfire Simple web-based real-time group chat @@ -580,8 +543,7 @@ Parameters: | --------- | ---- | -------- | ----------- | | `recipients` | string | yes | Comma-separated list of recipient email addresses | | `add_pusher` | boolean | no | Add pusher to recipients list | -| `notify_only_broken_jobs` | boolean | no | Notify only broken pipelines | - +| `notify_only_broken_pipelines` | boolean | no | Notify only broken pipelines | ### Delete Pipeline-Emails service diff --git a/doc/ci/quick_start/README.md b/doc/ci/quick_start/README.md index 76e86f3e3c3..30f209f80eb 100644 --- a/doc/ci/quick_start/README.md +++ b/doc/ci/quick_start/README.md @@ -207,15 +207,6 @@ you expected. You are also able to view the status of any commit in the various pages in GitLab, such as **Commits** and **Merge requests**. -## Enabling build emails - -If you want to receive e-mail notifications about the result status of the -jobs, you should explicitly enable the **Builds Emails** service under your -project's settings. - -For more information read the -[Builds emails service documentation](../../user/project/integrations/builds_emails.md). - ## Examples Visit the [examples README][examples] to see a list of examples using GitLab diff --git a/doc/project_services/builds_emails.md b/doc/project_services/builds_emails.md deleted file mode 100644 index ee54d865225..00000000000 --- a/doc/project_services/builds_emails.md +++ /dev/null @@ -1 +0,0 @@ -This document was moved to [user/project/integrations/builds_emails.md](../user/project/integrations/builds_emails.md). diff --git a/doc/user/project/integrations/builds_emails.md b/doc/user/project/integrations/builds_emails.md deleted file mode 100644 index f769dece242..00000000000 --- a/doc/user/project/integrations/builds_emails.md +++ /dev/null @@ -1,15 +0,0 @@ -# Enabling build emails - -By enabling this service, you will be able to receive e-mail notifications about -the result status of your builds. - -Navigate to the [Integrations page](project_services.md#accessing-the-project-services) -and select the **Builds emails** service to configure it. - -In the _Recipients_ area, provide a list of e-mails separated by comma. - -Check the _Add pusher_ checkbox if you want the committer to also receive -e-mail notifications about each build's status. - -If you enable the _Notify only broken builds_ option, e-mail notifications will -be sent only for failed builds. diff --git a/doc/user/project/integrations/mattermost.md b/doc/user/project/integrations/mattermost.md index cfb0931273d..3e77823a6aa 100644 --- a/doc/user/project/integrations/mattermost.md +++ b/doc/user/project/integrations/mattermost.md @@ -28,7 +28,6 @@ There, you will see a checkbox with the following events that can be triggered: - Merge request - Note - Tag push -- Build - Pipeline - Wiki page @@ -41,7 +40,6 @@ At the end, fill in your Mattermost details: | ----- | ----------- | | **Webhook** | The incoming webhook URL which you have to setup on Mattermost, it will be something like: http://mattermost.example/hooks/5xo… | | **Username** | Optional username which can be on messages sent to Mattermost. Fill this in if you want to change the username of the bot. | -| **Notify only broken builds** | If you choose to enable the **Build** event and you want to be only notified about failed builds. | | **Notify only broken pipelines** | If you choose to enable the **Pipeline** event and you want to be only notified about failed pipelines. | ![Mattermost configuration](img/mattermost_configuration.png) diff --git a/doc/user/project/integrations/project_services.md b/doc/user/project/integrations/project_services.md index 3cf1cc704a2..25400633de5 100644 --- a/doc/user/project/integrations/project_services.md +++ b/doc/user/project/integrations/project_services.md @@ -32,7 +32,6 @@ Click on the service links to see further configuration instructions and details | Assembla | Project Management Software (Source Commits Endpoint) | | [Atlassian Bamboo CI](bamboo.md) | A continuous integration and build server | | Buildkite | Continuous integration and deployments | -| [Builds emails](builds_emails.md) | Email the builds status to a list of recipients | | [Bugzilla](bugzilla.md) | Bugzilla issue tracker | | Campfire | Simple web-based real-time group chat | | Custom Issue Tracker | Custom issue tracker | @@ -48,6 +47,7 @@ Click on the service links to see further configuration instructions and details | [Kubernetes](kubernetes.md) | A containerized deployment service | | [Mattermost slash commands](mattermost_slash_commands.md) | Mattermost chat and ChatOps slash commands | | [Mattermost Notifications](mattermost.md) | Receive event notifications in Mattermost | +| Pipelines emails | Email the pipeline status to a list of recipients | | [Slack Notifications](slack.md) | Receive event notifications in Slack | | [Slack slash commands](slack_slash_commands.md) | Slack chat and ChatOps slash commands | | PivotalTracker | Project Management Software (Source Commits Endpoint) | diff --git a/doc/user/project/integrations/slack.md b/doc/user/project/integrations/slack.md index f27f9a726fc..e8b238351ca 100644 --- a/doc/user/project/integrations/slack.md +++ b/doc/user/project/integrations/slack.md @@ -25,7 +25,6 @@ There, you will see a checkbox with the following events that can be triggered: - Merge request - Note - Tag push -- Build - Pipeline - Wiki page @@ -38,7 +37,6 @@ At the end, fill in your Slack details: | ----- | ----------- | | **Webhook** | The [incoming webhook URL][slackhook] which you have to setup on Slack. | | **Username** | Optional username which can be on messages sent to Slack. Fill this in if you want to change the username of the bot. | -| **Notify only broken builds** | If you choose to enable the **Build** event and you want to be only notified about failed builds. | | **Notify only broken pipelines** | If you choose to enable the **Pipeline** event and you want to be only notified about failed pipelines. | After you are all done, click **Save changes** for the changes to take effect. diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md index be042ddf623..7a4f9f408f1 100644 --- a/doc/user/project/settings/import_export.md +++ b/doc/user/project/settings/import_export.md @@ -34,7 +34,7 @@ with all their related data and be moved into a new GitLab instance. | 8.10.0 | 0.1.2 | | 8.9.5 | 0.1.1 | | 8.9.0 | 0.1.0 | - + > The table reflects what GitLab version we updated the Import/Export version at. > For instance, 8.10.3 and 8.11 will have the same Import/Export version (0.1.3) > and the exports between them will be compatible. diff --git a/lib/api/services.rb b/lib/api/services.rb index be614bb8dc0..4e0c9cb1f63 100644 --- a/lib/api/services.rb +++ b/lib/api/services.rb @@ -107,26 +107,6 @@ module API desc: 'Enable SSL verification for communication' } ], - 'builds-email' => [ - { - required: true, - name: :recipients, - type: String, - desc: 'Comma-separated list of recipient email addresses' - }, - { - required: false, - name: :add_pusher, - type: Boolean, - desc: 'Add pusher to recipients list' - }, - { - required: false, - name: :notify_only_broken_jobs, - type: Boolean, - desc: 'Notify only broken jobs' - } - ], 'campfire' => [ { required: true, @@ -403,9 +383,9 @@ module API }, { required: false, - name: :notify_only_broken_jobs, + name: :notify_only_broken_pipelines, type: Boolean, - desc: 'Notify only broken jobs' + desc: 'Notify only broken pipelines' } ], 'pivotaltracker' => [ @@ -550,7 +530,6 @@ module API BambooService, BugzillaService, BuildkiteService, - BuildsEmailService, CampfireService, CustomIssueTrackerService, DroneCiService, diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml index 416194e57d7..ab74c8782f6 100644 --- a/lib/gitlab/import_export/import_export.yml +++ b/lib/gitlab/import_export/import_export.yml @@ -73,6 +73,9 @@ excluded_attributes: - :milestone_id award_emoji: - :awardable_id + statuses: + - :trace + - :token methods: labels: @@ -81,6 +84,7 @@ methods: - :type statuses: - :type + - :gl_project_id services: - :type merge_request_diff: diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index fae792237d9..d44563333a5 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -15,7 +15,7 @@ module Gitlab USER_REFERENCES = %w[author_id assignee_id updated_by_id user_id created_by_id merge_user_id resolved_by_id].freeze - PROJECT_REFERENCES = %w[project_id source_project_id gl_project_id target_project_id].freeze + PROJECT_REFERENCES = %w[project_id source_project_id target_project_id].freeze BUILD_MODELS = %w[Ci::Build commit_status].freeze @@ -98,12 +98,11 @@ module Gitlab end def generate_imported_object - if BUILD_MODELS.include?(@relation_name) # call #trace= method after assigning the other attributes - trace = @relation_hash.delete('trace') + if BUILD_MODELS.include?(@relation_name) + @relation_hash.delete('trace') # old export files have trace @relation_hash.delete('token') imported_object do |object| - object.trace = trace object.commit_id = nil end else @@ -121,7 +120,6 @@ module Gitlab # project_id may not be part of the export, but we always need to populate it if required. @relation_hash['project_id'] = project_id - @relation_hash['gl_project_id'] = project_id if @relation_hash['gl_project_id'] @relation_hash['target_project_id'] = project_id if @relation_hash['target_project_id'] end diff --git a/spec/controllers/projects/variables_controller_spec.rb b/spec/controllers/projects/variables_controller_spec.rb index e3f3b4fe8eb..1ecfe48475c 100644 --- a/spec/controllers/projects/variables_controller_spec.rb +++ b/spec/controllers/projects/variables_controller_spec.rb @@ -35,7 +35,7 @@ describe Projects::VariablesController do context 'updating a variable with valid characters' do before do - variable.gl_project_id = project.id + variable.project_id = project.id project.variables << variable end diff --git a/spec/factories/ci/runner_projects.rb b/spec/factories/ci/runner_projects.rb index 3372e5ab685..6712dd5d82e 100644 --- a/spec/factories/ci/runner_projects.rb +++ b/spec/factories/ci/runner_projects.rb @@ -1,6 +1,6 @@ FactoryGirl.define do factory :ci_runner_project, class: Ci::RunnerProject do runner_id 1 - gl_project_id 1 + project_id 1 end end diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index de42ab81fac..b4095095887 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -26,7 +26,7 @@ feature 'Admin updates settings', feature: true do fill_in 'Webhook', with: 'http://localhost' fill_in 'Username', with: 'test_user' fill_in 'service_push_channel', with: '#test_channel' - page.check('Notify only broken builds') + page.check('Notify only broken pipelines') check_all_events click_on 'Save' @@ -50,7 +50,6 @@ feature 'Admin updates settings', feature: true do page.check('Note') page.check('Issue') page.check('Merge request') - page.check('Build') page.check('Pipeline') end end diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz index 20cdfbae24f..399c1d478c5 100644 Binary files a/spec/features/projects/import_export/test_project_export.tar.gz and b/spec/features/projects/import_export/test_project_export.tar.gz differ diff --git a/spec/features/projects/services/slack_service_spec.rb b/spec/features/projects/services/slack_service_spec.rb index 16541f51d98..c0a4a1e4bf5 100644 --- a/spec/features/projects/services/slack_service_spec.rb +++ b/spec/features/projects/services/slack_service_spec.rb @@ -7,7 +7,7 @@ feature 'Projects > Slack service > Setup events', feature: true do background do service.fields - service.update_attributes(push_channel: 1, issue_channel: 2, merge_request_channel: 3, note_channel: 4, tag_push_channel: 5, build_channel: 6, wiki_page_channel: 7) + service.update_attributes(push_channel: 1, issue_channel: 2, merge_request_channel: 3, note_channel: 4, tag_push_channel: 5, pipeline_channel: 6, wiki_page_channel: 7) project.team << [user, :master] login_as(user) end @@ -20,7 +20,7 @@ feature 'Projects > Slack service > Setup events', feature: true do expect(page.find_field("service_merge_request_channel").value).to have_content '3' expect(page.find_field("service_note_channel").value).to have_content '4' expect(page.find_field("service_tag_push_channel").value).to have_content '5' - expect(page.find_field("service_build_channel").value).to have_content '6' + expect(page.find_field("service_pipeline_channel").value).to have_content '6' expect(page.find_field("service_wiki_page_channel").value).to have_content '7' end end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index e47956a365f..ddeb71730e7 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -130,7 +130,6 @@ project: - campfire_service - drone_ci_service - emails_on_push_service -- builds_email_service - pipelines_email_service - mattermost_slash_commands_service - slack_slash_commands_service diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json index c3d5c451a3c..d9b67426818 100644 --- a/spec/lib/gitlab/import_export/project.json +++ b/spec/lib/gitlab/import_export/project.json @@ -6507,7 +6507,6 @@ "tag": null, "yaml_errors": null, "committed_at": null, - "gl_project_id": 5, "status": "failed", "started_at": null, "finished_at": null, @@ -6565,7 +6564,6 @@ "artifacts_file": { "url": null }, - "gl_project_id": 5, "artifacts_metadata": { "url": null }, @@ -6603,7 +6601,6 @@ "artifacts_file": { "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/72/p5_build_artifacts.zip" }, - "gl_project_id": 5, "artifacts_metadata": { "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/72/p5_build_artifacts_metadata.gz" }, @@ -6624,7 +6621,6 @@ "tag": null, "yaml_errors": null, "committed_at": null, - "gl_project_id": 5, "status": "failed", "started_at": null, "finished_at": null, @@ -6659,7 +6655,6 @@ "artifacts_file": { "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/74/p5_build_artifacts.zip" }, - "gl_project_id": 5, "artifacts_metadata": { "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/74/p5_build_artifacts_metadata.gz" }, @@ -6695,7 +6690,6 @@ "artifacts_file": { "url": null }, - "gl_project_id": 5, "artifacts_metadata": { "url": null }, @@ -6716,7 +6710,6 @@ "tag": null, "yaml_errors": null, "committed_at": null, - "gl_project_id": 5, "status": "failed", "started_at": null, "finished_at": null, @@ -6751,7 +6744,6 @@ "artifacts_file": { "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/76/p5_build_artifacts.zip" }, - "gl_project_id": 5, "artifacts_metadata": { "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/76/p5_build_artifacts_metadata.gz" }, @@ -6787,7 +6779,6 @@ "artifacts_file": { "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/75/p5_build_artifacts.zip" }, - "gl_project_id": 5, "artifacts_metadata": { "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/75/p5_build_artifacts_metadata.gz" }, @@ -6808,7 +6799,6 @@ "tag": null, "yaml_errors": null, "committed_at": null, - "gl_project_id": 5, "status": "failed", "started_at": null, "finished_at": null, @@ -6843,7 +6833,6 @@ "artifacts_file": { "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/78/p5_build_artifacts.zip" }, - "gl_project_id": 5, "artifacts_metadata": { "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/78/p5_build_artifacts_metadata.gz" }, @@ -6879,7 +6868,6 @@ "artifacts_file": { "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/77/p5_build_artifacts.zip" }, - "gl_project_id": 5, "artifacts_metadata": { "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/77/p5_build_artifacts_metadata.gz" }, @@ -6900,7 +6888,6 @@ "tag": null, "yaml_errors": null, "committed_at": null, - "gl_project_id": 5, "status": "failed", "started_at": null, "finished_at": null, @@ -6935,7 +6922,6 @@ "artifacts_file": { "url": null }, - "gl_project_id": 5, "artifacts_metadata": { "url": null }, @@ -6971,7 +6957,6 @@ "artifacts_file": { "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/80/p5_build_artifacts.zip" }, - "gl_project_id": 5, "artifacts_metadata": { "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/80/p5_build_artifacts_metadata.gz" }, @@ -6985,11 +6970,10 @@ { "id": 123, "token": "cdbfasdf44a5958c83654733449e585", - "project_id": null, + "project_id": 5, "deleted_at": null, "created_at": "2017-01-16T15:25:28.637Z", - "updated_at": "2017-01-16T15:25:28.637Z", - "gl_project_id": 123 + "updated_at": "2017-01-16T15:25:28.637Z" } ], "deploy_keys": [ @@ -7047,7 +7031,7 @@ "updated_at": "2016-06-14T15:01:51.303Z", "active": false, "properties": { - "notify_only_broken_builds": true + "notify_only_broken_pipelines": true }, "template": false, "push_events": true, @@ -7055,7 +7039,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "pipeline_events": true, "category": "common", "default": false, "wiki_page_events": true @@ -7174,7 +7158,7 @@ "updated_at": "2016-06-14T15:01:51.219Z", "active": false, "properties": { - "notify_only_broken_builds": true + "notify_only_broken_pipelines": true }, "template": false, "push_events": true, @@ -7182,7 +7166,7 @@ "merge_requests_events": true, "tag_push_events": true, "note_events": true, - "build_events": true, + "pipeline_events": true, "category": "common", "default": false, "wiki_page_events": true @@ -7334,27 +7318,6 @@ "default": false, "wiki_page_events": true }, - { - "id": 85, - "title": "Builds emails", - "project_id": 5, - "created_at": "2016-06-14T15:01:51.090Z", - "updated_at": "2016-06-14T15:01:51.090Z", - "active": false, - "properties": { - "notify_only_broken_builds": true - }, - "template": false, - "push_events": true, - "issues_events": true, - "merge_requests_events": true, - "tag_push_events": true, - "note_events": true, - "build_events": true, - "category": "common", - "default": false, - "wiki_page_events": true - }, { "id": 84, "title": "Buildkite", @@ -7503,4 +7466,4 @@ "updated_at": "2016-09-23T11:58:28.000Z", "wiki_access_level": 20 } -} \ No newline at end of file +} diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb index f4a21c24fa1..c36f12dbd82 100644 --- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb @@ -129,6 +129,25 @@ describe Gitlab::ImportExport::ProjectTreeRestorer, services: true do expect(Ci::Build.where(token: 'abcd')).to be_empty end end + + context 'has restored the correct number of records' do + it 'has the correct number of merge requests' do + expect(@project.merge_requests.size).to eq(9) + end + + it 'has the correct number of triggers' do + expect(@project.triggers.size).to eq(1) + end + + it 'has the correct number of pipelines and statuses' do + expect(@project.pipelines.size).to eq(5) + + @project.pipelines.zip([2, 2, 2, 2, 2]) + .each do |(pipeline, expected_status_size)| + expect(pipeline.statuses.size).to eq(expected_status_size) + end + end + end end end diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml index c718e792461..042b7b0a20d 100644 --- a/spec/lib/gitlab/import_export/safe_model_attributes.yml +++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml @@ -176,7 +176,6 @@ Ci::Pipeline: - tag - yaml_errors - committed_at -- gl_project_id - status - started_at - finished_at @@ -211,7 +210,6 @@ CommitStatus: - target_url - description - artifacts_file -- gl_project_id - artifacts_metadata - erased_by_id - erased_at @@ -232,7 +230,6 @@ Ci::Variable: - encrypted_value - encrypted_value_salt - encrypted_value_iv -- gl_project_id Ci::Trigger: - id - token @@ -240,7 +237,6 @@ Ci::Trigger: - deleted_at - created_at - updated_at -- gl_project_id - owner_id - description DeployKey: diff --git a/spec/mailers/emails/builds_spec.rb b/spec/mailers/emails/builds_spec.rb deleted file mode 100644 index d968096783c..00000000000 --- a/spec/mailers/emails/builds_spec.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'spec_helper' -require 'email_spec' - -describe Notify do - include EmailSpec::Matchers - - include_context 'gitlab email notification' - - describe 'build notification email' do - let(:build) { create(:ci_build) } - let(:project) { build.project } - - shared_examples 'build email' do - it 'contains name of project' do - is_expected.to have_body_text build.project_name - end - - it 'contains link to project' do - is_expected.to have_body_text namespace_project_path(project.namespace, project) - end - end - - shared_examples 'an email with X-GitLab headers containing build details' do - it 'has X-GitLab-Build* headers' do - is_expected.to have_header 'X-GitLab-Build-Id', /#{build.id}/ - is_expected.to have_header 'X-GitLab-Build-Ref', /#{build.ref}/ - end - end - - describe 'build success' do - subject { Notify.build_success_email(build.id, 'wow@example.com') } - before { build.success } - - it_behaves_like 'build email' - it_behaves_like 'an email with X-GitLab headers containing build details' - it_behaves_like 'an email with X-GitLab headers containing project details' - - it 'has header indicating build status' do - is_expected.to have_header 'X-GitLab-Build-Status', 'success' - end - - it 'has the correct subject' do - is_expected.to have_subject /Build success for/ - end - end - - describe 'build fail' do - subject { Notify.build_fail_email(build.id, 'wow@example.com') } - before { build.drop } - - it_behaves_like 'build email' - it_behaves_like 'an email with X-GitLab headers containing build details' - it_behaves_like 'an email with X-GitLab headers containing project details' - - it 'has header indicating build status' do - is_expected.to have_header 'X-GitLab-Build-Status', 'failed' - end - - it 'has the correct subject' do - is_expected.to have_subject /Build failed for/ - end - end - end -end diff --git a/spec/migrations/migrate_build_events_to_pipeline_events_spec.rb b/spec/migrations/migrate_build_events_to_pipeline_events_spec.rb new file mode 100644 index 00000000000..57eb03e3c80 --- /dev/null +++ b/spec/migrations/migrate_build_events_to_pipeline_events_spec.rb @@ -0,0 +1,74 @@ +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20170301205640_migrate_build_events_to_pipeline_events.rb') + +# This migration uses multiple threads, and thus different transactions. This +# means data created in this spec may not be visible to some threads. To work +# around this we use the TRUNCATE cleaning strategy. +describe MigrateBuildEventsToPipelineEvents, truncate: true do + let(:migration) { described_class.new } + let(:project_with_pipeline_service) { create(:empty_project) } + let(:project_with_build_service) { create(:empty_project) } + + before do + ActiveRecord::Base.connection.execute <<-SQL + INSERT INTO services (properties, build_events, pipeline_events, type) + VALUES + ('{"notify_only_broken_builds":true}', true, false, 'SlackService') + , ('{"notify_only_broken_builds":true}', true, false, 'MattermostService') + , ('{"notify_only_broken_builds":true}', true, false, 'HipchatService') + ; + SQL + + ActiveRecord::Base.connection.execute <<-SQL + INSERT INTO services + (properties, build_events, pipeline_events, type, project_id) + VALUES + ('{"notify_only_broken_builds":true}', true, false, + 'BuildsEmailService', #{project_with_pipeline_service.id}) + , ('{"notify_only_broken_pipelines":true}', false, true, + 'PipelinesEmailService', #{project_with_pipeline_service.id}) + , ('{"notify_only_broken_builds":true}', true, false, + 'BuildsEmailService', #{project_with_build_service.id}) + ; + SQL + end + + describe '#up' do + before do + silence_migration = Module.new do + # rubocop:disable Rails/Delegate + def execute(query) + connection.execute(query) + end + end + + migration.extend(silence_migration) + migration.up + end + + it 'migrates chat service properly' do + [SlackService, MattermostService, HipchatService].each do |service| + expect(service.count).to eq(1) + + verify_service_record(service.first) + end + end + + it 'migrates pipelines email service only if it has none before' do + Project.find_each do |project| + pipeline_service_count = + project.services.where(type: 'PipelinesEmailService').count + + expect(pipeline_service_count).to eq(1) + + verify_service_record(project.pipelines_email_service) + end + end + + def verify_service_record(service) + expect(service.notify_only_broken_pipelines).to be(true) + expect(service.build_events).to be(false) + expect(service.pipeline_events).to be(true) + end + end +end diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index fd6ea2d6722..8dbcf50ee0c 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -795,8 +795,8 @@ describe Ci::Build, :models do describe '#merge_request' do def create_mr(build, pipeline, factory: :merge_request, created_at: Time.now) - create(factory, source_project_id: pipeline.gl_project_id, - target_project_id: pipeline.gl_project_id, + create(factory, source_project: pipeline.project, + target_project: pipeline.project, source_branch: build.ref, created_at: created_at) end diff --git a/spec/models/ci/variable_spec.rb b/spec/models/ci/variable_spec.rb index bee9f714849..048d25869bc 100644 --- a/spec/models/ci/variable_spec.rb +++ b/spec/models/ci/variable_spec.rb @@ -6,7 +6,7 @@ describe Ci::Variable, models: true do let(:secret_value) { 'secret' } it { is_expected.to validate_presence_of(:key) } - it { is_expected.to validate_uniqueness_of(:key).scoped_to(:gl_project_id) } + it { is_expected.to validate_uniqueness_of(:key).scoped_to(:project_id) } it { is_expected.to validate_length_of(:key).is_at_most(255) } it { is_expected.to allow_value('foo').for(:key) } it { is_expected.not_to allow_value('foo bar').for(:key) } diff --git a/spec/models/project_services/builds_email_service_spec.rb b/spec/models/project_services/builds_email_service_spec.rb deleted file mode 100644 index 0194f9e2563..00000000000 --- a/spec/models/project_services/builds_email_service_spec.rb +++ /dev/null @@ -1,111 +0,0 @@ -require 'spec_helper' - -describe BuildsEmailService do - let(:data) do - Gitlab::DataBuilder::Build.build(create(:ci_build)) - end - - describe 'Validations' do - context 'when service is active' do - before { subject.active = true } - - it { is_expected.to validate_presence_of(:recipients) } - - context 'when pusher is added' do - before { subject.add_pusher = true } - - it { is_expected.not_to validate_presence_of(:recipients) } - end - end - - context 'when service is inactive' do - before { subject.active = false } - - it { is_expected.not_to validate_presence_of(:recipients) } - end - end - - describe '#test_data' do - let(:build) { create(:ci_build) } - let(:project) { build.project } - let(:user) { create(:user) } - - before { project.team << [user, :developer] } - - it 'builds test data' do - data = subject.test_data(project) - - expect(data[:object_kind]).to eq("build") - end - end - - describe '#test' do - it 'sends email' do - data = Gitlab::DataBuilder::Build.build(create(:ci_build)) - subject.recipients = 'test@gitlab.com' - - expect(BuildEmailWorker).to receive(:perform_async) - - subject.test(data) - end - - context 'notify only failed builds is true' do - it 'sends email' do - data = Gitlab::DataBuilder::Build.build(create(:ci_build)) - data[:build_status] = "success" - subject.recipients = 'test@gitlab.com' - - expect(subject).not_to receive(:notify_only_broken_builds) - expect(BuildEmailWorker).to receive(:perform_async) - - subject.test(data) - end - end - end - - describe '#execute' do - it 'sends email' do - subject.recipients = 'test@gitlab.com' - data[:build_status] = 'failed' - - expect(BuildEmailWorker).to receive(:perform_async) - - subject.execute(data) - end - - it 'does not send email with succeeded build and notify_only_broken_builds on' do - expect(subject).to receive(:notify_only_broken_builds).and_return(true) - data[:build_status] = 'success' - - expect(BuildEmailWorker).not_to receive(:perform_async) - - subject.execute(data) - end - - it 'does not send email with failed build and build_allow_failure is true' do - data[:build_status] = 'failed' - data[:build_allow_failure] = true - - expect(BuildEmailWorker).not_to receive(:perform_async) - - subject.execute(data) - end - - it 'does not send email with unknown build status' do - data[:build_status] = 'foo' - - expect(BuildEmailWorker).not_to receive(:perform_async) - - subject.execute(data) - end - - it 'does not send email when recipients list is empty' do - subject.recipients = ' ,, ' - data[:build_status] = 'failed' - - expect(BuildEmailWorker).not_to receive(:perform_async) - - subject.execute(data) - end - end -end diff --git a/spec/models/project_services/chat_message/build_message_spec.rb b/spec/models/project_services/chat_message/build_message_spec.rb deleted file mode 100644 index 3bd7ec18ae0..00000000000 --- a/spec/models/project_services/chat_message/build_message_spec.rb +++ /dev/null @@ -1,77 +0,0 @@ -require 'spec_helper' - -describe ChatMessage::BuildMessage do - subject { described_class.new(args) } - - let(:args) do - { - sha: '97de212e80737a608d939f648d959671fb0a0142', - ref: 'develop', - tag: false, - - project_name: 'project_name', - project_url: 'http://example.gitlab.com', - build_id: 1, - build_name: build_name, - build_stage: stage, - - commit: { - status: status, - author_name: 'hacker', - author_url: 'http://example.gitlab.com/hacker', - duration: duration, - }, - } - end - - let(:message) { build_message } - let(:stage) { 'test' } - let(:status) { 'success' } - let(:build_name) { 'rspec' } - let(:duration) { 10 } - - context 'build succeeded' do - let(:status) { 'success' } - let(:color) { 'good' } - let(:message) { build_message('passed') } - - it 'returns a message with information about succeeded build' do - expect(subject.pretext).to be_empty - expect(subject.fallback).to eq(message) - expect(subject.attachments).to eq([text: message, color: color]) - end - end - - context 'build failed' do - let(:status) { 'failed' } - let(:color) { 'danger' } - - it 'returns a message with information about failed build' do - expect(subject.pretext).to be_empty - expect(subject.fallback).to eq(message) - expect(subject.attachments).to eq([text: message, color: color]) - end - end - - it 'returns a message with information on build' do - expect(subject.fallback).to include("on build ") - end - - it 'returns a message with stage name' do - expect(subject.fallback).to include("of stage #{stage}") - end - - it 'returns a message with link to author' do - expect(subject.fallback).to include("by ") - end - - def build_message(status_text = status, stage_text = stage, build_text = build_name) - ":" \ - " Commit " \ - " of branch" \ - " by #{status_text}" \ - " on build " \ - " of stage #{stage_text} in #{duration} #{'second'.pluralize(duration)}" - end -end diff --git a/spec/models/project_services/hipchat_service_spec.rb b/spec/models/project_services/hipchat_service_spec.rb index bf422ac7ce1..1200ae7eb22 100644 --- a/spec/models/project_services/hipchat_service_spec.rb +++ b/spec/models/project_services/hipchat_service_spec.rb @@ -280,13 +280,14 @@ describe HipchatService, models: true do end end - context 'build events' do - let(:pipeline) { create(:ci_empty_pipeline) } - let(:build) { create(:ci_build, pipeline: pipeline) } - let(:data) { Gitlab::DataBuilder::Build.build(build.reload) } + context 'pipeline events' do + let(:pipeline) { create(:ci_empty_pipeline, user: create(:user)) } + let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) } context 'for failed' do - before { build.drop } + before do + pipeline.drop + end it "calls Hipchat API" do hipchat.execute(data) @@ -295,35 +296,36 @@ describe HipchatService, models: true do end it "creates a build message" do - message = hipchat.send(:create_build_message, data) + message = hipchat.__send__(:create_pipeline_message, data) project_url = project.web_url project_name = project.name_with_namespace.gsub(/\s/, '') - sha = data[:sha] - ref = data[:ref] - ref_type = data[:tag] ? 'tag' : 'branch' - duration = data[:commit][:duration] + pipeline_attributes = data[:object_attributes] + ref = pipeline_attributes[:ref] + ref_type = pipeline_attributes[:tag] ? 'tag' : 'branch' + duration = pipeline_attributes[:duration] + user_name = data[:user][:name] expect(message).to eq("#{project_name}: " \ - "Commit #{Commit.truncate_sha(sha)} " \ + "Pipeline ##{pipeline.id} " \ "of #{ref} #{ref_type} " \ - "by #{data[:commit][:author_name]} failed in #{duration} second(s)") + "by #{user_name} failed in #{duration} second(s)") end end context 'for succeeded' do before do - build.success + pipeline.succeed end it "calls Hipchat API" do - hipchat.notify_only_broken_builds = false + hipchat.notify_only_broken_pipelines = false hipchat.execute(data) expect(WebMock).to have_requested(:post, api_url).once end it "notifies only broken" do - hipchat.notify_only_broken_builds = true + hipchat.notify_only_broken_pipelines = true hipchat.execute(data) expect(WebMock).not_to have_requested(:post, api_url).once end @@ -349,17 +351,19 @@ describe HipchatService, models: true do context 'with a successful build' do it 'uses the green color' do - build_data = { object_kind: 'build', commit: { status: 'success' } } + data = { object_kind: 'pipeline', + object_attributes: { status: 'success' } } - expect(hipchat.__send__(:message_options, build_data)).to eq({ notify: false, color: 'green' }) + expect(hipchat.__send__(:message_options, data)).to eq({ notify: false, color: 'green' }) end end context 'with a failed build' do it 'uses the red color' do - build_data = { object_kind: 'build', commit: { status: 'failed' } } + data = { object_kind: 'pipeline', + object_attributes: { status: 'failed' } } - expect(hipchat.__send__(:message_options, build_data)).to eq({ notify: false, color: 'red' }) + expect(hipchat.__send__(:message_options, data)).to eq({ notify: false, color: 'red' }) end end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index ff1defcd32d..618ce2b6d53 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -29,8 +29,7 @@ describe Project, models: true do it { is_expected.to have_one(:campfire_service).dependent(:destroy) } it { is_expected.to have_one(:drone_ci_service).dependent(:destroy) } it { is_expected.to have_one(:emails_on_push_service).dependent(:destroy) } - it { is_expected.to have_one(:builds_email_service).dependent(:destroy) } - it { is_expected.to have_one(:emails_on_push_service).dependent(:destroy) } + it { is_expected.to have_one(:pipelines_email_service).dependent(:destroy) } it { is_expected.to have_one(:irker_service).dependent(:destroy) } it { is_expected.to have_one(:pivotaltracker_service).dependent(:destroy) } it { is_expected.to have_one(:hipchat_service).dependent(:destroy) } diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb index 65af4e13118..8567817147b 100644 --- a/spec/services/ci/retry_build_service_spec.rb +++ b/spec/services/ci/retry_build_service_spec.rb @@ -19,7 +19,7 @@ describe Ci::RetryBuildService, :services do erased_at].freeze IGNORE_ACCESSORS = - %i[type lock_version target_url gl_project_id deploy job_id base_tags + %i[type lock_version target_url base_tags commit_id deployments erased_by_id last_deployment project_id runner_id tag_taggings taggings tags trigger_request_id user_id].freeze diff --git a/spec/workers/build_email_worker_spec.rb b/spec/workers/build_email_worker_spec.rb deleted file mode 100644 index 542e674c150..00000000000 --- a/spec/workers/build_email_worker_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'spec_helper' - -describe BuildEmailWorker do - include EmailHelpers - include RepoHelpers - - let(:build) { create(:ci_build) } - let(:user) { create(:user) } - let(:data) { Gitlab::DataBuilder::Build.build(build) } - - subject { BuildEmailWorker.new } - - before do - allow(build).to receive(:execute_hooks).and_return(false) - build.success - end - - describe "#perform" do - it "sends mail" do - subject.perform(build.id, [user.email], data.stringify_keys) - - email = ActionMailer::Base.deliveries.last - expect(email.subject).to include('Build success for') - expect(email.to).to eq([user.email]) - end - - it "gracefully handles an input SMTP error" do - reset_delivered_emails! - allow(Notify).to receive(:build_success_email).and_raise(Net::SMTPFatalError) - - subject.perform(build.id, [user.email], data.stringify_keys) - - expect(ActionMailer::Base.deliveries.count).to eq(0) - end - end -end