diff options
author | Z.J. van de Weg <zegerjan@gitlab.com> | 2016-10-04 16:03:13 +0200 |
---|---|---|
committer | Z.J. van de Weg <zegerjan@gitlab.com> | 2016-10-14 11:07:00 +0200 |
commit | 6a4f71008390752e6b5574a9e9bdf277732d852d (patch) | |
tree | cedc380844ee38ec20b89916a6038d3c4aeaa1c1 /app | |
parent | e4c74ffe3ed93815b131445796e63e2127eb8c3e (diff) | |
download | gitlab-ce-6a4f71008390752e6b5574a9e9bdf277732d852d.tar.gz |
Show what time ago a MR was deployed
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/merge_request_widget.js.es6 (renamed from app/assets/javascripts/merge_request_widget.js) | 55 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/merge_requests.scss | 4 | ||||
-rw-r--r-- | app/controllers/projects/merge_requests_controller.rb | 31 | ||||
-rw-r--r-- | app/models/environment.rb | 8 | ||||
-rw-r--r-- | app/models/merge_request.rb | 9 | ||||
-rw-r--r-- | app/models/repository.rb | 8 | ||||
-rw-r--r-- | app/views/projects/merge_requests/widget/_heading.html.haml | 16 | ||||
-rw-r--r-- | app/views/projects/merge_requests/widget/_show.html.haml | 2 |
8 files changed, 113 insertions, 20 deletions
diff --git a/app/assets/javascripts/merge_request_widget.js b/app/assets/javascripts/merge_request_widget.js.es6 index 7bbcdf59838..7c727cf214f 100644 --- a/app/assets/javascripts/merge_request_widget.js +++ b/app/assets/javascripts/merge_request_widget.js.es6 @@ -1,7 +1,26 @@ -(function() { + ((global) => { var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - this.MergeRequestWidget = (function() { + const DEPLOYMENT_TEMPLATE = `<div class="mr-widget-heading" id="<%- id %>"> + <div class="ci_widget ci-success"> + <%= ci_success_icon %> + <span> + Deployed to + <a href="<%- url %>" target="_blank" class="environment"> + <%- name %> + </a> + <span class="js-environment-timeago" data-toggle="tooltip" data-placement="top" data-title="<%- deployed_at_formatted %>"> + <%- deployed_at %> + </span> + <a class="js-environment-link" href="<%- external_url %>" target="_blank"> + <i class="fa fa-external-link"></i> + View on <%- external_url_formatted %> + </a> + </span> + </div> + </div>`; + + global.MergeRequestWidget = (function() { function MergeRequestWidget(opts) { // Initialize MergeRequestWidget behavior // @@ -10,6 +29,7 @@ // ci_status_url - String, URL to use to check CI status // this.opts = opts; + this.$widgetBody = $('.mr-widget-body'); $('#modal_merge_info').modal({ show: false }); @@ -20,6 +40,7 @@ this.clearEventListeners(); this.addEventListeners(); this.getCIStatus(false); + this.retrieveSuccessIcon(); this.pollCIStatus(); notifyPermissions(); } @@ -48,6 +69,12 @@ })(this)); }; + MergeRequestWidget.prototype.retrieveSuccessIcon = function() { + const $ciSuccessIcon = $('.js-success-icon'); + this.$ciSuccessIcon = $ciSuccessIcon.html(); + $ciSuccessIcon.remove(); + } + MergeRequestWidget.prototype.mergeInProgress = function(deleteSourceBranch) { if (deleteSourceBranch == null) { deleteSourceBranch = false; @@ -62,7 +89,7 @@ urlSuffix = deleteSourceBranch ? '?deleted_source_branch=true' : ''; return window.location.href = window.location.pathname + urlSuffix; } else if (data.merge_error) { - return $('.mr-widget-body').html("<h4>" + data.merge_error + "</h4>"); + return this.$widgetBody.html("<h4>" + data.merge_error + "</h4>"); } else { callback = function() { return merge_request_widget.mergeInProgress(deleteSourceBranch); @@ -118,6 +145,7 @@ if (data.status === '') { return; } + if (data.environments && data.environments.length) _this.renderEnvironments(data.environments); if (_this.firstCICheck || data.status !== _this.opts.ci_status && (data.status != null)) { _this.opts.ci_status = data.status; _this.showCIStatus(data.status); @@ -150,6 +178,25 @@ })(this)); }; + MergeRequestWidget.prototype.renderEnvironments = function(environments) { + for (let i = 0; i < environments.length; i++) { + const environment = environments[i]; + if ($(`.mr-state-widget #${ environment.id }`).length) return; + const $template = $(DEPLOYMENT_TEMPLATE); + if (!environment.external_url) $('.js-environment-link', $template).remove(); + if (environment.deployed_at) { + environment.deployed_at = $.timeago(environment.deployed_at) + '.'; + } else { + $('.js-environment-timeago', $template).remove(); + environment.name += '.'; + } + environment.ci_success_icon = this.$ciSuccessIcon; + const templateString = _.unescape($template[0].outerHTML); + const template = _.template(templateString)(environment) + this.$widgetBody.before(template); + } + }; + MergeRequestWidget.prototype.showCIStatus = function(state) { var allowed_states; if (state == null) { @@ -190,4 +237,4 @@ })(); -}).call(this); + })(window.gl || (window.gl = {})); diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 7cf69c56d15..96d5547154d 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -121,6 +121,10 @@ color: #5c5d5e; } + .js-deployment-link { + display: inline-block; + } + .mr-widget-body { h4 { font-weight: 600; diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 869d96b86f4..28225fbb762 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -393,11 +393,40 @@ class Projects::MergeRequestsController < Projects::ApplicationController end end + environments = @merge_request.environments + deployments = @merge_request.deployments + + if environments.present? + environments = environments.select { |e| can?(current_user, :read_environment, e) }.map do |environment| + project = environment.project + deployment = deployments.find { |d| d.environment == environment } + + environment = { + name: environment.name, + id: environment.id, + url: namespace_project_environment_path(project.namespace, project, environment), + external_url: environment.external_url, + deployed_at: deployment ? deployment.created_at : nil + } + + if environment[:external_url] + environment[:external_url_formatted] = environment[:external_url].gsub(/\A.*?:\/\//, '') + end + + if environment[:deployed_at] + environment[:deployed_at_formatted] = environment[:deployed_at].to_time.in_time_zone.to_s(:medium) + end + + environment + end + end + response = { title: merge_request.title, sha: merge_request.diff_head_commit.short_id, status: status, - coverage: coverage + coverage: coverage, + environments: environments } render json: response diff --git a/app/models/environment.rb b/app/models/environment.rb index f0f3ee23223..1c7d06906f3 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -48,6 +48,14 @@ class Environment < ActiveRecord::Base self.name == "production" end + def deployment_id_for(commit) + ref = project.repository.ref_name_for_sha(ref_path, commit.sha) + + return nil unless ref + + ref.split('/').last.to_i + end + def ref_path "refs/environments/#{Shellwords.shellescape(name)}" end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index a743bf313ae..ec8c09f83db 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -685,6 +685,15 @@ class MergeRequest < ActiveRecord::Base !pipeline || pipeline.success? end + def deployments + deployment_ids = + environments.map do |environment| + environment.deployment_id_for(diff_head_commit) + end.compact + + Deployments.find(deployment_ids) + end + def environments return [] unless diff_head_commit diff --git a/app/models/repository.rb b/app/models/repository.rb index 608c99eed46..37833cf004f 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -719,6 +719,14 @@ class Repository end end + def ref_name_for_sha(environment_ref_path, sha) + args = %W(#{Gitlab.config.git.bin_path} for-each-ref --count=1 #{environment_ref_path} --contains #{sha}) + + # Not found -> ["", 0] + # Found -> ["b8d95eb4969eefacb0a58f6a28f6803f8070e7b9 commit\trefs/environments/production/77\n", 0] + Gitlab::Popen.popen(args, path_to_repo).first.split.last + end + def refs_contains_sha(ref_type, sha) args = %W(#{Gitlab.config.git.bin_path} #{ref_type} --contains #{sha}) names = Gitlab::Popen.popen(args, path_to_repo).first diff --git a/app/views/projects/merge_requests/widget/_heading.html.haml b/app/views/projects/merge_requests/widget/_heading.html.haml index 5b7f83c344f..cda8f0b7de6 100644 --- a/app/views/projects/merge_requests/widget/_heading.html.haml +++ b/app/views/projects/merge_requests/widget/_heading.html.haml @@ -44,17 +44,5 @@ = icon("times-circle") Could not connect to the CI server. Please check your settings and try again. -- @merge_request.environments.sort_by(&:name).each do |environment| - - if can?(current_user, :read_environment, environment) - .mr-widget-heading - .ci_widget.ci-success - = ci_icon_for_status("success") - %span - Deployed to - = succeed '.' do - = link_to environment.name, environment_path(environment), class: 'environment' - - external_url = environment.external_url - - if external_url - = link_to external_url, target: '_blank' do - %span.hidden-xs View on #{external_url.gsub(/\A.*?:\/\//, '')} - = icon('external-link', right: true) + .js-success-icon.hidden + = ci_icon_for_status('success') diff --git a/app/views/projects/merge_requests/widget/_show.html.haml b/app/views/projects/merge_requests/widget/_show.html.haml index ea618263a4a..856ec1e0bee 100644 --- a/app/views/projects/merge_requests/widget/_show.html.haml +++ b/app/views/projects/merge_requests/widget/_show.html.haml @@ -33,4 +33,4 @@ merge_request_widget.clearEventListeners(); } - merge_request_widget = new MergeRequestWidget(opts); + merge_request_widget = new window.gl.MergeRequestWidget(opts); |