environment_status.rb 1.88 KB
Newer Older
1 2 3 4 5
# frozen_string_literal: true

class EnvironmentStatus
  include Gitlab::Utils::StrongMemoize

6
  attr_reader :project, :environment, :merge_request, :sha
7 8 9

  delegate :id, to: :environment
  delegate :name, to: :environment
10
  delegate :status, to: :deployment, allow_nil: true
11
  delegate :deployed_at, to: :deployment, allow_nil: true
12

13
  def self.for_merge_request(mr, user)
14
    build_environments_status(mr, user, mr.actual_head_pipeline)
15 16 17 18 19
  end

  def self.after_merge_request(mr, user)
    return [] unless mr.merged?

20
    build_environments_status(mr, user, mr.merge_pipeline)
21 22
  end

23 24
  def initialize(project, environment, merge_request, sha)
    @project = project
25 26
    @environment = environment
    @merge_request = merge_request
27
    @sha = sha
28 29 30 31
  end

  def deployment
    strong_memoize(:deployment) do
32
      Deployment.where(environment: environment).find_by_sha(sha)
33 34 35
    end
  end

36 37 38
  def changes
    return [] if project.route_map_for(sha).nil?

39
    changed_files.map { |file| build_change(file) }.compact
40 41 42 43 44 45 46 47 48 49 50
  end

  def changed_files
    merge_request.merge_request_diff
      .merge_request_diff_files.where(deleted_file: false)
  end

  private

  PAGE_EXTENSIONS = /\A\.(s?html?|php|asp|cgi|pl)\z/i.freeze

51
  def build_change(file)
52 53 54 55 56 57 58 59 60 61 62
    public_path = project.public_path_for_source_path(file.new_path, sha)
    return if public_path.nil?

    ext = File.extname(public_path)
    return if ext.present? && ext !~ PAGE_EXTENSIONS

    {
      path: public_path,
      external_url: environment.external_url_for(file.new_path, sha)
    }
  end
63

64 65 66 67
  def self.build_environments_status(mr, user, pipeline)
    return [] unless pipeline

    pipeline.environments.available.map do |environment|
68
      next unless Ability.allowed?(user, :read_environment, environment)
69

70
      EnvironmentStatus.new(pipeline.project, environment, mr, pipeline.sha)
71
    end.compact
72 73
  end
  private_class_method :build_environments_status
74
end