summaryrefslogtreecommitdiff
path: root/app/models/ci
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/ci')
-rw-r--r--app/models/ci/build.rb52
-rw-r--r--app/models/ci/pipeline.rb24
-rw-r--r--app/models/ci/stage.rb6
3 files changed, 71 insertions, 11 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 88c46076df6..cb76cdf5981 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -9,8 +9,16 @@ module Ci
has_many :deployments, as: :deployable
+ # The "environment" field for builds is a String, and is the unexpanded name
+ def persisted_environment
+ @persisted_environment ||= Environment.find_by(
+ name: expanded_environment_name,
+ project_id: gl_project_id
+ )
+ end
+
serialize :options
- serialize :yaml_variables
+ serialize :yaml_variables, Gitlab::Serialize::Ci::Variables
validates :coverage, numericality: true, allow_blank: true
validates_presence_of :ref
@@ -100,6 +108,12 @@ module Ci
end
end
+ def detailed_status(current_user)
+ Gitlab::Ci::Status::Build::Factory
+ .new(self, current_user)
+ .fabricate!
+ end
+
def manual?
self.when == 'manual'
end
@@ -123,8 +137,13 @@ module Ci
end
end
+ def cancelable?
+ active?
+ end
+
def retryable?
- project.builds_enabled? && commands.present? && complete?
+ project.builds_enabled? && commands.present? &&
+ (success? || failed? || canceled?)
end
def retried?
@@ -132,11 +151,11 @@ module Ci
end
def expanded_environment_name
- ExpandVariables.expand(environment, variables) if environment
+ ExpandVariables.expand(environment, simple_variables) if environment
end
def has_environment?
- self.environment.present?
+ environment.present?
end
def starts_environment?
@@ -148,7 +167,7 @@ module Ci
end
def environment_action
- self.options.fetch(:environment, {}).fetch(:action, 'start')
+ self.options.fetch(:environment, {}).fetch(:action, 'start') if self.options
end
def outdated_deployment?
@@ -184,12 +203,25 @@ module Ci
project.build_timeout
end
- def variables
+ # A slugified version of the build ref, suitable for inclusion in URLs and
+ # domain names. Rules:
+ #
+ # * Lowercased
+ # * Anything not matching [a-z0-9-] is replaced with a -
+ # * Maximum length is 63 bytes
+ def ref_slug
+ slugified = ref.to_s.downcase
+ slugified.gsub(/[^a-z0-9]/, '-')[0..62]
+ end
+
+ # Variables whose value does not depend on other variables
+ def simple_variables
variables = predefined_variables
variables += project.predefined_variables
variables += pipeline.predefined_variables
variables += runner.predefined_variables if runner
variables += project.container_registry_variables
+ variables += project.deployment_variables if has_environment?
variables += yaml_variables
variables += user_variables
variables += project.secret_variables
@@ -197,6 +229,13 @@ module Ci
variables
end
+ # All variables, including those dependent on other variables
+ def variables
+ variables = simple_variables
+ variables += persisted_environment.predefined_variables if persisted_environment.present?
+ variables
+ end
+
def merge_request
merge_requests = MergeRequest.includes(:merge_request_diff)
.where(source_branch: ref, source_project_id: pipeline.gl_project_id)
@@ -518,6 +557,7 @@ module Ci
{ key: 'CI_BUILD_REF', value: sha, public: true },
{ key: 'CI_BUILD_BEFORE_SHA', value: before_sha, public: true },
{ key: 'CI_BUILD_REF_NAME', value: ref, public: true },
+ { key: 'CI_BUILD_REF_SLUG', value: ref_slug, public: true },
{ key: 'CI_BUILD_NAME', value: name, public: true },
{ key: 'CI_BUILD_STAGE', value: stage, public: true },
{ key: 'CI_SERVER_NAME', value: 'GitLab', public: true },
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index fda8228a1e9..48354cdbefb 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -88,8 +88,24 @@ module Ci
end
# ref can't be HEAD or SHA, can only be branch/tag name
+ scope :latest, ->(ref = nil) do
+ max_id = unscope(:select)
+ .select("max(#{quoted_table_name}.id)")
+ .group(:ref, :sha)
+
+ if ref
+ where(id: max_id, ref: ref)
+ else
+ where(id: max_id)
+ end
+ end
+
+ def self.latest_status(ref = nil)
+ latest(ref).status
+ end
+
def self.latest_successful_for(ref)
- where(ref: ref).order(id: :desc).success.first
+ success.latest(ref).first
end
def self.truncate_sha(sha)
@@ -336,8 +352,10 @@ module Ci
.select { |merge_request| merge_request.head_pipeline.try(:id) == self.id }
end
- def detailed_status
- Gitlab::Ci::Status::Pipeline::Factory.new(self).fabricate!
+ def detailed_status(current_user)
+ Gitlab::Ci::Status::Pipeline::Factory
+ .new(self, current_user)
+ .fabricate!
end
private
diff --git a/app/models/ci/stage.rb b/app/models/ci/stage.rb
index d2a37c0a827..7ef59445d77 100644
--- a/app/models/ci/stage.rb
+++ b/app/models/ci/stage.rb
@@ -22,8 +22,10 @@ module Ci
@status ||= statuses.latest.status
end
- def detailed_status
- Gitlab::Ci::Status::Stage::Factory.new(self).fabricate!
+ def detailed_status(current_user)
+ Gitlab::Ci::Status::Stage::Factory
+ .new(self, current_user)
+ .fabricate!
end
def statuses