diff --git a/CHANGELOG b/CHANGELOG index 3a50d0c066b01accd257db5e558d466e81ca918b..ccc6084678798ba129f5e3495084b2d103598459 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -40,6 +40,7 @@ v 8.11.0 (unreleased) - Update `timeago` plugin to use multiple string/locale settings - Remove unused images (ClemMakesApps) - Limit git rev-list output count to one in forced push check + - Show deployment status on merge requests with external URLs - Clean up unused routes (Josef Strzibny) - Fix issue on empty project to allow developers to only push to protected branches if given permission - Add green outline to New Branch button. !5447 (winniehell) diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 0a661e529f0c96e364b64a0fcccbc364c9adda1e..b463626951849c30664185ed8630981257c577d4 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -69,6 +69,10 @@ &.ci-success { color: $gl-success; + + a.environment { + color: inherit; + } } &.ci-success_with_warnings { @@ -126,7 +130,6 @@ &.has-conflicts .fa-exclamation-triangle { color: $gl-warning; } - } p:last-child { diff --git a/app/models/deployment.rb b/app/models/deployment.rb index 1a7cd60817e7505fdc40728091efb6f53a843283..1e338889714ccd5b69980fc5ad57a725258a0b5c 100644 --- a/app/models/deployment.rb +++ b/app/models/deployment.rb @@ -36,4 +36,10 @@ class Deployment < ActiveRecord::Base def manual_actions deployable.try(:other_actions) end + + def includes_commit?(commit) + return false unless commit + + project.repository.is_ancestor?(commit.id, sha) + end end diff --git a/app/models/environment.rb b/app/models/environment.rb index baed106e8c884e313ddc587f9572d107da840f5a..75e6f869786e5bbc513ce1a677b0889fe97a6bcc 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -25,4 +25,10 @@ class Environment < ActiveRecord::Base def nullify_external_url self.external_url = nil if self.external_url.blank? end + + def includes_commit?(commit) + return false unless last_deployment + + last_deployment.includes_commit?(commit) + end end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index f6d0d0c98f594e6e65d38bac16b8ff9e3dde22f5..fe799382fd0083bc7f44516f5cb1260ff465e992 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -591,6 +591,14 @@ class MergeRequest < ActiveRecord::Base !pipeline || pipeline.success? end + def environments + return unless diff_head_commit + + target_project.environments.select do |environment| + environment.includes_commit?(diff_head_commit) + end + end + def state_human_name if merged? "Merged" diff --git a/app/views/projects/merge_requests/widget/_heading.html.haml b/app/views/projects/merge_requests/widget/_heading.html.haml index 6ef640bb6543d1446ca42b3d71b6543b9260aedf..494695a03a50e3363efe1f8bf06b2ef01aab6493 100644 --- a/app/views/projects/merge_requests/widget/_heading.html.haml +++ b/app/views/projects/merge_requests/widget/_heading.html.haml @@ -42,3 +42,16 @@ .ci_widget.ci-error{style: "display:none"} = icon("times-circle") Could not connect to the CI server. Please check your settings and try again. + +- @merge_request.environments.each do |environment| + .mr-widget-heading + .ci_widget.ci-success + = ci_icon_for_status("success") + %span.hidden-sm + Deployed to + = succeed '.' do + = link_to environment.name, namespace_project_environment_path(@project.namespace, @project, environment), class: 'environment' + - external_url = environment.external_url + - if external_url + = link_to external_url, target: '_blank' do + = icon('external-link', text: "View on #{external_url.gsub(/\A.*?:\/\//, '')}", right: true) diff --git a/db/schema.rb b/db/schema.rb index 1de2cdcf026bf81c4aa1c3119cebb5ebe95cca8d..f008a6bd7a7dcb3ef181710ce1357ad8d8b1d32e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -589,12 +589,12 @@ ActiveRecord::Schema.define(version: 20160810142633) do t.datetime "locked_at" t.integer "updated_by_id" t.string "merge_error" - t.text "merge_params" t.boolean "merge_when_build_succeeds", default: false, null: false t.integer "merge_user_id" t.string "merge_commit_sha" t.datetime "deleted_at" t.string "in_progress_merge_commit_sha" + t.text "merge_params" end add_index "merge_requests", ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb index 7df3df4bb9e652016122d0e6ed99b605a15ca28e..bfff639ad78c55961c1707caec1649a48768b0f0 100644 --- a/spec/models/deployment_spec.rb +++ b/spec/models/deployment_spec.rb @@ -15,4 +15,28 @@ describe Deployment, models: true do it { is_expected.to validate_presence_of(:ref) } it { is_expected.to validate_presence_of(:sha) } + + describe '#includes_commit?' do + let(:project) { create(:project) } + let(:environment) { create(:environment, project: project) } + let(:deployment) do + create(:deployment, environment: environment, sha: project.commit.id) + end + + context 'when there is no project commit' do + it 'returns false' do + commit = project.commit('feature') + + expect(deployment.includes_commit?(commit)).to be false + end + end + + context 'when they share the same tree branch' do + it 'returns true' do + commit = project.commit + + expect(deployment.includes_commit?(commit)).to be true + end + end + end end diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index 8a84ac0a7c7cb601cc695a2d8b55a97b8ca75ddb..c881897926e36b4172dc977fa8dc3fec10f97c71 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -30,4 +30,37 @@ describe Environment, models: true do expect(env.external_url).to be_nil end end + + describe '#includes_commit?' do + context 'without a last deployment' do + it "returns false" do + expect(environment.includes_commit?('HEAD')).to be false + end + end + + context 'with a last deployment' do + let(:project) { create(:project) } + let(:environment) { create(:environment, project: project) } + + let!(:deployment) do + create(:deployment, environment: environment, sha: project.commit('master').id) + end + + context 'in the same branch' do + it 'returns true' do + expect(environment.includes_commit?(RepoHelpers.sample_commit)).to be true + end + end + + context 'not in the same branch' do + before do + deployment.update(sha: project.commit('feature').id) + end + + it 'returns false' do + expect(environment.includes_commit?(RepoHelpers.sample_commit)).to be false + end + end + end + end end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 3270b877c1a7b53d111668c3a3543a99d0295e60..35a4418ebb3682dc91febc474f445e51692633b1 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -674,6 +674,21 @@ describe MergeRequest, models: true do end end + describe "#environments" do + let(:project) { create(:project) } + let!(:environment) { create(:environment, project: project) } + let!(:environment1) { create(:environment, project: project) } + let!(:environment2) { create(:environment, project: project) } + let(:merge_request) { create(:merge_request, source_project: project) } + + it 'selects deployed environments' do + create(:deployment, environment: environment, sha: project.commit('master').id) + create(:deployment, environment: environment1, sha: project.commit('feature').id) + + expect(merge_request.environments).to eq [environment] + end + end + describe "#reload_diff" do let(:note) { create(:diff_note_on_merge_request, project: subject.project, noteable: subject) } diff --git a/spec/views/projects/merge_requests/_heading.html.haml_spec.rb b/spec/views/projects/merge_requests/_heading.html.haml_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..733b2dfa7ffe9c30e7441b0714fe945112503175 --- /dev/null +++ b/spec/views/projects/merge_requests/_heading.html.haml_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe 'projects/merge_requests/widget/_heading' do + include Devise::TestHelpers + + context 'when released to an environment' do + let(:project) { merge_request.target_project } + let(:merge_request) { create(:merge_request, :merged) } + let(:environment) { create(:environment, project: project) } + let!(:deployment) do + create(:deployment, environment: environment, sha: project.commit('master').id) + end + + before do + assign(:merge_request, merge_request) + assign(:project, project) + + render + end + + it 'displays that the environment is deployed' do + expect(rendered).to match("Deployed to") + expect(rendered).to match("#{environment.name}") + end + end +end