Commit 12dd5ac2 authored by Kamil Trzciński's avatar Kamil Trzciński Committed by Robert Speicher
Browse files

All CI offline migrations

parent 9c1a9782fe90
......@@ -37,7 +37,6 @@ module ServiceParams
:namespace,
:new_issue_url,
:notify,
:notify_only_broken_builds,
:notify_only_broken_pipelines,
:password,
:priority,
......
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 @@ class Build < CommitStatus
def persisted_environment
@persisted_environment ||= Environment.find_by(
name: expanded_environment_name,
project_id: gl_project_id
project: project
)
end
......@@ -223,7 +223,8 @@ def variables
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 @@ def merge_request
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 @@ def update_erased!(user = nil)
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 @@ class Pipeline < ActiveRecord::Base
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 @@ class Runner < ActiveRecord::Base
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 @@ class Runner < ActiveRecord::Base
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
......
module Ci
class RunnerProject < ActiveRecord::Base
extend Ci::Model
belongs_to :runner
belongs_to :project, foreign_key: :gl_project_id
belongs_to :project
validates :runner_id, uniqueness: { scope: :gl_project_id }
validates :runner_id, uniqueness: { scope: :project_id }
end
end
......@@ -4,7 +4,7 @@ class Trigger < ActiveRecord::Base
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 @@ def has_trace?
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 @@ def update_forks_visibility_level
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 @@ def update_forks_visibility_level
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
......
# 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
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 @@ def initialize_properties
if properties.nil?
self.properties = {}
self.notify_only_broken_builds = true
self.notify_only_broken_pipelines = true
end
end
......@@ -27,7 +26,7 @@ def can_test?
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 @@ def get_message(object_kind, data)
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 @@ def is_update?(data)
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 @@ def fields
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 @@ def create_message(data)
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 @@ def create_note_message(data)
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 @@ def humanized_status(status)
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 @@ def default_fields
[
{ 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 @@ def default_fields
[
{ 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 @@ def self.available_services_names
assembla
bamboo
buildkite
builds_email
bugzilla
campfire
custom_issue_tracker
......
......@@ -877,7 +877,7 @@ def can_be_removed?
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 @@ def builds_for_shared_runner