Merge branch 'all-ci-offline-migrations' into 'master'
All CI offline migrations See merge request !9730
This commit is contained in:
commit
0eff4f14cc
67 changed files with 494 additions and 963 deletions
|
@ -37,7 +37,6 @@ module ServiceParams
|
|||
:namespace,
|
||||
:new_issue_url,
|
||||
:notify,
|
||||
:notify_only_broken_builds,
|
||||
:notify_only_broken_pipelines,
|
||||
:password,
|
||||
:priority,
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 '_'." }
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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'
|
||||
|
|
|
@ -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 = "<a href=\"#{project_url}/commits/#{CGI.escape(ref)}\">#{ref}</a>"
|
||||
commit_link = "<a href=\"#{project_url}/commit/#{CGI.escape(sha)}/builds\">#{Commit.truncate_sha(sha)}</a>"
|
||||
pipeline_url = "<a href=\"#{project_url}/pipelines/#{pipeline_id}\">##{pipeline_id}</a>"
|
||||
|
||||
"#{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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -215,7 +215,6 @@ class Service < ActiveRecord::Base
|
|||
assembla
|
||||
bamboo
|
||||
buildkite
|
||||
builds_email
|
||||
bugzilla
|
||||
campfire
|
||||
custom_issue_tracker
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)}
|
|
@ -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) %>
|
|
@ -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)}
|
|
@ -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) %>
|
|
@ -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
|
6
changelogs/unreleased/23993-drop-ci_projects.yml
Normal file
6
changelogs/unreleased/23993-drop-ci_projects.yml
Normal file
|
@ -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
|
|
@ -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:
|
4
changelogs/unreleased/remove-unused-ci-tables.yml
Normal file
4
changelogs/unreleased/remove-unused-ci-tables.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Remove various unused CI tables and columns
|
||||
merge_request: 9639
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Rename table ci_commits to ci_pipelines
|
||||
merge_request: 9638
|
||||
author:
|
|
@ -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
|
||||
|
|
34
db/migrate/20170222143317_drop_ci_projects.rb
Normal file
34
db/migrate/20170222143317_drop_ci_projects.rb
Normal file
|
@ -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
|
28
db/migrate/20170222143500_remove_old_project_id_columns.rb
Normal file
28
db/migrate/20170222143500_remove_old_project_id_columns.rb
Normal file
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
116
db/schema.rb
116
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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
This document was moved to [user/project/integrations/builds_emails.md](../user/project/integrations/builds_emails.md).
|
|
@ -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.
|
|
@ -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)
|
||||
|
|
|
@ -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) |
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Binary file not shown.
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -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
|
|
@ -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 <http://example.gitlab.com/builds/1|#{build_name}>")
|
||||
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 <http://example.gitlab.com/hacker|hacker>")
|
||||
end
|
||||
|
||||
def build_message(status_text = status, stage_text = stage, build_text = build_name)
|
||||
"<http://example.gitlab.com|project_name>:" \
|
||||
" Commit <http://example.gitlab.com/commit/" \
|
||||
"97de212e80737a608d939f648d959671fb0a0142/builds|97de212e>" \
|
||||
" of <http://example.gitlab.com/commits/develop|develop> branch" \
|
||||
" by <http://example.gitlab.com/hacker|hacker> #{status_text}" \
|
||||
" on build <http://example.gitlab.com/builds/1|#{build_text}>" \
|
||||
" of stage #{stage_text} in #{duration} #{'second'.pluralize(duration)}"
|
||||
end
|
||||
end
|
|
@ -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("<a href=\"#{project_url}\">#{project_name}</a>: " \
|
||||
"Commit <a href=\"#{project_url}/commit/#{sha}/builds\">#{Commit.truncate_sha(sha)}</a> " \
|
||||
"Pipeline <a href=\"#{project_url}/pipelines/#{pipeline.id}\">##{pipeline.id}</a> " \
|
||||
"of <a href=\"#{project_url}/commits/#{ref}\">#{ref}</a> #{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
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in a new issue