Add 'View on [env]' link to blobs and individual files in diffs
This commit is contained in:
parent
d147688af4
commit
27f2ca9418
|
@ -30,6 +30,9 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def show
|
||||
branch_name = @ref if @repository.branch_exists?(@ref)
|
||||
@environment = @project.latest_environment_for(@commit, ref: branch_name)
|
||||
@environment = nil unless can?(current_user, :read_environment, @environment)
|
||||
end
|
||||
|
||||
def edit
|
||||
|
|
|
@ -95,6 +95,9 @@ class Projects::CommitController < Projects::ApplicationController
|
|||
|
||||
@diffs = commit.diffs(opts)
|
||||
@notes_count = commit.notes.count
|
||||
|
||||
@environment = @project.latest_environment_for(@commit)
|
||||
@environment = nil unless can?(current_user, :read_environment, @environment)
|
||||
end
|
||||
|
||||
def define_note_vars
|
||||
|
|
|
@ -57,6 +57,10 @@ class Projects::CompareController < Projects::ApplicationController
|
|||
|
||||
@diffs = @compare.diffs(diff_options)
|
||||
|
||||
branch_name = @head_ref if @repository.branch_exists?(@head_ref)
|
||||
@environment = @project.latest_environment_for(@commit, ref: branch_name)
|
||||
@environment = nil unless can?(current_user, :read_environment, @environment)
|
||||
|
||||
@diff_notes_disabled = true
|
||||
@grouped_diff_discussions = {}
|
||||
end
|
||||
|
|
|
@ -103,6 +103,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
@environment = @merge_request.latest_environment
|
||||
@environment = nil unless can?(current_user, :read_environment, @environment)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { define_discussion_vars }
|
||||
format.json do
|
||||
|
@ -245,7 +248,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
|||
end
|
||||
@diff_notes_disabled = true
|
||||
|
||||
render json: { html: view_to_html_string('projects/merge_requests/_new_diffs', diffs: @diffs) }
|
||||
@environment = @merge_request.latest_environment
|
||||
@environment = nil unless can?(current_user, :read_environment, @environment)
|
||||
|
||||
render json: { html: view_to_html_string('projects/merge_requests/_new_diffs', diffs: @diffs, environment: @environment) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -205,6 +205,17 @@ module CommitsHelper
|
|||
end
|
||||
end
|
||||
|
||||
def view_on_environment_btn(commit_sha, diff_new_path, environment)
|
||||
return unless environment && commit_sha
|
||||
|
||||
external_url = environment.external_url_for(diff_new_path, commit_sha)
|
||||
return unless external_url
|
||||
|
||||
link_to(external_url, class: 'btn btn-file-option has-tooltip', target: '_blank', title: "View on #{environment.formatted_external_url}", data: { container: 'body' }) do
|
||||
icon('external-link')
|
||||
end
|
||||
end
|
||||
|
||||
def truncate_sha(sha)
|
||||
Commit.truncate_sha(sha)
|
||||
end
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1307,10 +1307,17 @@ class Project < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def environments_for(ref, commit: nil, with_tags: false)
|
||||
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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
.btn-group
|
||||
= view_on_environment_btn(@commit.sha, @path, @environment) if @environment
|
||||
|
||||
.btn-group.tree-btn-group
|
||||
= link_to 'Raw', namespace_project_raw_path(@project.namespace, @project, @id),
|
||||
class: 'btn btn-sm', target: '_blank'
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
= render "ci_menu"
|
||||
- else
|
||||
.block-connector
|
||||
= render "projects/diffs/diffs", diffs: @diffs
|
||||
= render "projects/diffs/diffs", diffs: @diffs, environment: @environment
|
||||
= render "projects/notes/notes_with_form"
|
||||
- if can_collaborate_with_project?
|
||||
- %w(revert cherry-pick).each do |type|
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
- if @commits.present?
|
||||
= render "projects/commits/commit_list"
|
||||
= render "projects/diffs/diffs", diffs: @diffs
|
||||
= render "projects/diffs/diffs", diffs: @diffs, environment: @environment
|
||||
- else
|
||||
.light-well
|
||||
.center
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
- environment = local_assigns.fetch(:environment, nil)
|
||||
- show_whitespace_toggle = local_assigns.fetch(:show_whitespace_toggle, true)
|
||||
- can_create_note = !@diff_notes_disabled && can?(current_user, :create_note, diffs.project)
|
||||
- diff_files = diffs.diff_files
|
||||
|
@ -30,4 +31,4 @@
|
|||
- file_hash = hexdigest(diff_file.file_path)
|
||||
|
||||
= render 'projects/diffs/file', file_hash: file_hash, project: diffs.project,
|
||||
diff_file: diff_file, diff_commit: diff_commit, blob: blob
|
||||
diff_file: diff_file, diff_commit: diff_commit, blob: blob, environment: environment
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
- environment = local_assigns.fetch(:environment, nil)
|
||||
.diff-file.file-holder{ id: file_hash, data: diff_file_html_data(project, diff_file.file_path, diff_commit.id) }
|
||||
.file-title
|
||||
= render "projects/diffs/file_header", diff_file: diff_file, blob: blob, diff_commit: diff_commit, project: project, url: "##{file_hash}"
|
||||
|
@ -14,5 +15,6 @@
|
|||
blob: blob, link_opts: link_opts)
|
||||
|
||||
= view_file_btn(diff_commit.id, diff_file.new_path, project)
|
||||
= view_on_environment_btn(diff_commit.id, diff_file.new_path, environment) if environment
|
||||
|
||||
= render 'projects/diffs/content', diff_file: diff_file, diff_commit: diff_commit, blob: blob, project: project
|
||||
|
|
|
@ -1 +1 @@
|
|||
= render "projects/diffs/diffs", diffs: @diffs, show_whitespace_toggle: false
|
||||
= render "projects/diffs/diffs", diffs: @diffs, environment: @environment, show_whitespace_toggle: false
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
- if @merge_request_diff.collected? || @merge_request_diff.overflow?
|
||||
= render 'projects/merge_requests/show/versions'
|
||||
= render "projects/diffs/diffs", diffs: @diffs
|
||||
= render "projects/diffs/diffs", diffs: @diffs, environment: @environment
|
||||
- elsif @merge_request_diff.empty?
|
||||
.nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Add 'View on [env]' link to blobs and individual files in diffs
|
||||
merge_request:
|
||||
author:
|
Loading…
Reference in New Issue