diff options
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/ci/pipeline.rb | 8 | ||||
-rw-r--r-- | app/models/environment.rb | 18 | ||||
-rw-r--r-- | app/models/merge_request.rb | 6 | ||||
-rw-r--r-- | app/models/project.rb | 47 | ||||
-rw-r--r-- | app/models/repository.rb | 17 |
5 files changed, 86 insertions, 10 deletions
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index fab8497ec7d..8db53ea56dd 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -283,13 +283,7 @@ module Ci def ci_yaml_file return @ci_yaml_file if defined?(@ci_yaml_file) - @ci_yaml_file ||= begin - blob = project.repository.blob_at(sha, '.gitlab-ci.yml') - blob.load_all_data!(project.repository) - blob.data - rescue - nil - end + @ci_yaml_file ||= project.repository.ci_yaml_file(sha) end def has_yaml_errors? diff --git a/app/models/environment.rb b/app/models/environment.rb index 577367f1eed..909249dacca 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -51,6 +51,14 @@ class Environment < ActiveRecord::Base state :stopped end + def self.latest_for_commit(environments, commit) + environments.sort_by do |environment| + deployment = environment.first_deployment_for(commit) + + deployment.try(:created_at) || DateTime.parse('1970-01-01') + end.last + end + def predefined_variables [ { key: 'CI_ENVIRONMENT_NAME', value: name, public: true }, @@ -171,6 +179,16 @@ class Environment < ActiveRecord::Base self.slug = slugified end + def external_url_for(path, commit_sha) + return unless self.external_url + + public_path = project.public_path_for_source_path(path, commit_sha) + return unless public_path + + # TODO: Verify this can't be used for XSS + URI.join(external_url, public_path).to_s + end + private # Slugifying a name may remove the uniqueness guarantee afforded by it being diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 082adcafcc8..0155073a1c9 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -729,6 +729,12 @@ class MergeRequest < ActiveRecord::Base end end + def latest_environment + return @latest_environment if defined?(@latest_environment) + + @latest_environment = Environment.latest_for_commit(environments, diff_head_commit) + end + def state_human_name if merged? "Merged" diff --git a/app/models/project.rb b/app/models/project.rb index 7c5fdad5122..ad22ab7577e 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1307,10 +1307,17 @@ class Project < ActiveRecord::Base end def environments_for(ref, commit: nil, with_tags: false) - deployments_query = with_tags ? 'ref = ? OR tag IS TRUE' : 'ref = ?' + deps = + if ref + deployments_query = with_tags ? 'ref = ? OR tag IS TRUE' : 'ref = ?' + deployments.where(deployments_query, ref.to_s) + elsif commit + deps = deployments.where(sha: commit.sha) + else + Deployment.none + end - environment_ids = deployments - .where(deployments_query, ref.to_s) + environment_ids = deps .group(:environment_id) .select(:environment_id) @@ -1324,12 +1331,46 @@ class Project < ActiveRecord::Base end end + def latest_environment_for(commit, ref: nil) + environments = environments_for(ref, commit: commit) + Environment.latest_for_commit(environments, commit) + end + def environments_recently_updated_on_branch(branch) environments_for(branch).select do |environment| environment.recently_updated_on_branch?(branch) end end + def route_map_for_commit(commit_sha) + @route_maps_by_commit ||= Hash.new do |h, sha| + h[sha] = begin + data = repository.route_map_file(sha) + next unless data + + # TODO: Validate + YAML.safe_load(data).map do |mapping| + { + source: Regexp.new("^#{mapping['source'][1...-1]}$"), + public: mapping['public'] + } + end + end + end + + @route_maps_by_commit[commit_sha] + end + + def public_path_for_source_path(path, commit_sha) + map = route_map_for_commit(commit_sha) + return unless map + + mapping = map.find { |mapping| path =~ mapping[:source] } + return unless mapping + + path.sub(mapping[:source], mapping[:public]) + end + private def cross_namespace_reference?(from) diff --git a/app/models/repository.rb b/app/models/repository.rb index 7cf09c52bf4..9aa0cc250f0 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -35,6 +35,9 @@ class Repository avatar: :avatar } + ROUTE_MAP_PATH = '.gitlab/route-map.yml' + GITLAB_CI_YML_PATH = '.gitlab-ci.yml' + # Wraps around the given method and caches its output in Redis and an instance # variable. # @@ -1184,6 +1187,20 @@ class Repository end end + def route_map_file(sha) + blob = blob_at(sha, ROUTE_MAP_PATH) + return unless blob + blob.load_all_data!(self) + blob.data + end + + def ci_yaml_file(sha) + blob = blob_at(sha, GITLAB_CI_YML_PATH) + return unless blob + blob.load_all_data!(self) + blob.data + end + private def git_action(index, action) |