1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
# == Schema Information
#
# Table name: ci_projects
#
# id :integer not null, primary key
# name :string(255)
# timeout :integer default(3600), not null
# created_at :datetime
# updated_at :datetime
# token :string(255)
# default_ref :string(255)
# path :string(255)
# always_build :boolean default(FALSE), not null
# polling_interval :integer
# public :boolean default(FALSE), not null
# ssh_url_to_repo :string(255)
# gitlab_id :integer
# allow_git_fetch :boolean default(TRUE), not null
# email_recipients :string(255) default(""), not null
# email_add_pusher :boolean default(TRUE), not null
# email_only_broken_builds :boolean default(TRUE), not null
# skip_refs :string(255)
# coverage_regex :string(255)
# shared_runners_enabled :boolean default(FALSE)
# generated_yaml_config :text
#
module Ci
class Project < ActiveRecord::Base
extend Ci::Model
include Ci::ProjectStatus
belongs_to :gl_project, class_name: '::Project', foreign_key: :gitlab_id
has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject'
has_many :runners, through: :runner_projects, class_name: 'Ci::Runner'
has_many :events, dependent: :destroy, class_name: 'Ci::Event'
has_many :variables, dependent: :destroy, class_name: 'Ci::Variable'
has_many :triggers, dependent: :destroy, class_name: 'Ci::Trigger'
accepts_nested_attributes_for :variables, allow_destroy: true
delegate :name_with_namespace, :path_with_namespace, :web_url, :http_url_to_repo, :ssh_url_to_repo, to: :gl_project
#
# Validations
#
validates_presence_of :timeout, :token, :default_ref, :gitlab_id
validates_uniqueness_of :gitlab_id
validates :polling_interval,
presence: true,
if: ->(project) { project.always_build.present? }
before_validation :set_default_values
class << self
include Ci::CurrentSettings
def unassigned(runner)
joins("LEFT JOIN #{Ci::RunnerProject.table_name} ON #{Ci::RunnerProject.table_name}.project_id = #{Ci::Project.table_name}.id " \
"AND #{Ci::RunnerProject.table_name}.runner_id = #{runner.id}").
where("#{Ci::RunnerProject.table_name}.project_id" => nil)
end
def ordered_by_last_commit_date
last_commit_subquery = "(SELECT gl_project_id, MAX(committed_at) committed_at FROM #{Ci::Commit.table_name} GROUP BY gl_project_id)"
joins("LEFT JOIN #{last_commit_subquery} AS last_commit ON #{Ci::Project.table_name}.gitlab_id = last_commit.gl_project_id").
joins(:gl_project).
order("CASE WHEN last_commit.committed_at IS NULL THEN 1 ELSE 0 END, last_commit.committed_at DESC")
end
end
def name
name_with_namespace
end
def path
path_with_namespace
end
def gitlab_url
web_url
end
def any_runners?(&block)
if runners.active.any?(&block)
return true
end
shared_runners_enabled && Ci::Runner.shared.active.any?(&block)
end
def set_default_values
self.token = SecureRandom.hex(15) if self.token.blank?
self.default_ref ||= 'master'
end
def tracked_refs
@tracked_refs ||= default_ref.split(",").map { |ref| ref.strip }
end
def valid_token? token
self.token && self.token == token
end
def no_running_builds?
# Get running builds not later than 3 days ago to ignore hangs
builds.running.where("updated_at > ?", 3.days.ago).empty?
end
def email_notification?
email_add_pusher || email_recipients.present?
end
def timeout_in_minutes
timeout / 60
end
def timeout_in_minutes=(value)
self.timeout = value.to_i * 60
end
def coverage_enabled?
coverage_regex.present?
end
# Build a clone-able repo url
# using http and basic auth
def repo_url_with_auth
auth = "gitlab-ci-token:#{token}@"
http_url_to_repo.sub(/^https?:\/\//) do |prefix|
prefix + auth
end
end
def setup_finished?
commits.any?
end
def commits
gl_project.ci_commits.ordered
end
def builds
gl_project.ci_builds
end
end
end
|