Skip to content
Snippets Groups Projects
Commit 27f2ca94 authored by Douwe Maan's avatar Douwe Maan
Browse files

Add 'View on [env]' link to blobs and individual files in diffs

parent d147688a
No related branches found
No related tags found
No related merge requests found
Showing
with 129 additions and 16 deletions
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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?
Loading
Loading
Loading
Loading
@@ -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 },
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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"
Loading
Loading
Loading
Loading
@@ -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)
 
Loading
Loading
@@ -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)
Loading
Loading
Loading
Loading
@@ -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.
#
Loading
Loading
@@ -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)
Loading
Loading
.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'
Loading
Loading
Loading
Loading
@@ -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|
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
- 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
Loading
Loading
@@ -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
- 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}"
Loading
Loading
@@ -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
= render "projects/diffs/diffs", diffs: @diffs, show_whitespace_toggle: false
= render "projects/diffs/diffs", diffs: @diffs, environment: @environment, show_whitespace_toggle: false
- 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}
---
title: Add 'View on [env]' link to blobs and individual files in diffs
merge_request:
author:
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment