From d5905d15ff5c447c1304cfb08881bf162b4f9939 Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Thu, 3 Oct 2019 12:57:20 -0600 Subject: [PATCH 01/23] initial commit --- lib/gitlab/badge/release/latestrelease.rb | 34 ++++++++++++++++++ lib/gitlab/badge/release/metadata.rb | 29 +++++++++++++++ lib/gitlab/badge/release/template.rb | 44 +++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 lib/gitlab/badge/release/latestrelease.rb create mode 100644 lib/gitlab/badge/release/metadata.rb create mode 100644 lib/gitlab/badge/release/template.rb diff --git a/lib/gitlab/badge/release/latestrelease.rb b/lib/gitlab/badge/release/latestrelease.rb new file mode 100644 index 00000000000000..542e1e309e7d5c --- /dev/null +++ b/lib/gitlab/badge/release/latestrelease.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Gitlab + module Badge + module Release + + class LatestRelease < Badge::Base + attr_reader :project, :ref + + def initialize(project, ref) + @project = project + @ref = ref + end + + def entity + 'latest release' + end + + def status + @release = @project.releases.last.tag || 'none' + end + + def metadata + @metadata ||= Release::Metadata.new(self) + end + + def template + @template ||= Release::Template.new(self) + end + + end + end + end +end diff --git a/lib/gitlab/badge/release/metadata.rb b/lib/gitlab/badge/release/metadata.rb new file mode 100644 index 00000000000000..49b81b12ad18c3 --- /dev/null +++ b/lib/gitlab/badge/release/metadata.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Gitlab + module Badge + module Release + ## + # Class that describes release badge metadata + # + class Metadata < Badge::Metadata + def initialize(badge) + @project = badge.project + @ref = badge.ref + end + + def title + 'latest release' + end + + def image_url + release_project_badges_url(@project, @ref, format: :svg) + end + + def link_url + project_release_url(@project, id: @ref) + end + end + end + end +end diff --git a/lib/gitlab/badge/release/template.rb b/lib/gitlab/badge/release/template.rb new file mode 100644 index 00000000000000..7e05fdc1e0d369 --- /dev/null +++ b/lib/gitlab/badge/release/template.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Gitlab + module Badge + module Release + ## + # Class that represents a release badge template. + # + # Template object will be passed to badge.svg.erb template. + # + class Template < Badge::Template + STATUS_COLOR = { + latest: '#4c1', + none: '#e05d44', + }.freeze + + def initialize(badge) + @entity = badge.entity + @status = badge.status + end + + def key_text + @entity.to_s + end + + def value_text + @status.to_s + end + + def key_width + 62 + end + + def value_width + 54 + end + + def value_color + STATUS_COLOR[@status.to_sym] || STATUS_COLOR[:latest] + end + end + end + end +end -- GitLab From 79de5e51bad22a5d7b5e61418376991e08305c7c Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Thu, 3 Oct 2019 14:07:01 -0600 Subject: [PATCH 02/23] change latest release badge color to blue --- lib/gitlab/badge/release/template.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/badge/release/template.rb b/lib/gitlab/badge/release/template.rb index 7e05fdc1e0d369..9edbf6f5a91f55 100644 --- a/lib/gitlab/badge/release/template.rb +++ b/lib/gitlab/badge/release/template.rb @@ -10,8 +10,8 @@ module Release # class Template < Badge::Template STATUS_COLOR = { - latest: '#4c1', - none: '#e05d44', + latest: '#3076af', + none: '#e05d44' }.freeze def initialize(badge) -- GitLab From a7c1ca996f7a148798c36f29dc922172849df58a Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Thu, 3 Oct 2019 15:19:04 -0600 Subject: [PATCH 03/23] cleanup whitespace for static analysis --- lib/gitlab/badge/release/latestrelease.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/badge/release/latestrelease.rb b/lib/gitlab/badge/release/latestrelease.rb index 542e1e309e7d5c..b9de635775c8d9 100644 --- a/lib/gitlab/badge/release/latestrelease.rb +++ b/lib/gitlab/badge/release/latestrelease.rb @@ -3,7 +3,9 @@ module Gitlab module Badge module Release - + ## + # Latest Release badge + # class LatestRelease < Badge::Base attr_reader :project, :ref @@ -27,7 +29,6 @@ def metadata def template @template ||= Release::Template.new(self) end - end end end -- GitLab From d0ba75202c7e6fcb6235a25aa26c6d11b9c93c38 Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Thu, 3 Oct 2019 16:39:22 -0600 Subject: [PATCH 04/23] add changelog --- changelogs/unreleased/18098-add-release-badge.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelogs/unreleased/18098-add-release-badge.yml diff --git a/changelogs/unreleased/18098-add-release-badge.yml b/changelogs/unreleased/18098-add-release-badge.yml new file mode 100644 index 00000000000000..41cb22e449b96f --- /dev/null +++ b/changelogs/unreleased/18098-add-release-badge.yml @@ -0,0 +1,5 @@ +--- +title: Added "Latest Release" badge, which shows the tag and links to release +merge_request: 18098 +author: +type: added -- GitLab From 1df0bf6897a5e5de5d7c434d529dc624030f53b0 Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Mon, 7 Oct 2019 11:58:30 -0700 Subject: [PATCH 05/23] rename latestrelease to latest_release --- .../badge/release/{latestrelease.rb => latest_release.rb} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename lib/gitlab/badge/release/{latestrelease.rb => latest_release.rb} (93%) diff --git a/lib/gitlab/badge/release/latestrelease.rb b/lib/gitlab/badge/release/latest_release.rb similarity index 93% rename from lib/gitlab/badge/release/latestrelease.rb rename to lib/gitlab/badge/release/latest_release.rb index b9de635775c8d9..95d9225885ba13 100644 --- a/lib/gitlab/badge/release/latestrelease.rb +++ b/lib/gitlab/badge/release/latest_release.rb @@ -6,7 +6,7 @@ module Release ## # Latest Release badge # - class LatestRelease < Badge::Base + class Latest_Release < Badge::Base attr_reader :project, :ref def initialize(project, ref) -- GitLab From 1612dc614db9ef29d6987b1c3d8e06ecb4b247f2 Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Mon, 7 Oct 2019 11:59:10 -0700 Subject: [PATCH 06/23] add render action and url route --- app/controllers/projects/badges_controller.rb | 7 +++++++ config/routes/project.rb | 1 + 2 files changed, 8 insertions(+) diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb index 66b51b1779060b..332fc153745a37 100644 --- a/app/controllers/projects/badges_controller.rb +++ b/app/controllers/projects/badges_controller.rb @@ -20,6 +20,13 @@ def coverage render_badge coverage_report end + def coverage + latest_release = Gitlab::Badge::Release::Latest_Release + .new(project, params[:ref], params[:job]) + + render_badge latest_release + end + private def badge_layout diff --git a/config/routes/project.rb b/config/routes/project.rb index 5225cd5b054074..5353b07139f3cc 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -591,6 +591,7 @@ get :build, to: "badges#pipeline" get :pipeline get :coverage + get :release end end end -- GitLab From d82991dcbfdf6658592eeb028cb447284727a53f Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Mon, 7 Oct 2019 11:59:31 -0700 Subject: [PATCH 07/23] add release badge to ci_cd controller --- app/controllers/projects/settings/ci_cd_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index 0d61c3cc0313b2..08dddba95c252d 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -109,7 +109,8 @@ def define_badges_variables @ref = params[:ref] || @project.default_branch || 'master' @badges = [Gitlab::Badge::Pipeline::Status, - Gitlab::Badge::Coverage::Report] + Gitlab::Badge::Coverage::Report, + Gitlab::Badge::Release::Latest_Release] @badges.map! do |badge| badge.new(@project, @ref).metadata -- GitLab From bd8b171e634a5fa7638bbd70c19ad715a427032b Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Wed, 9 Oct 2019 09:30:40 -0700 Subject: [PATCH 08/23] placeholder for specs --- .../badge/release/latest_release_spec.rb | 108 +++++++++++++ .../lib/gitlab/badge/release/metadata_spec.rb | 32 ++++ .../lib/gitlab/badge/release/template_spec.rb | 142 ++++++++++++++++++ 3 files changed, 282 insertions(+) create mode 100644 spec/lib/gitlab/badge/release/latest_release_spec.rb create mode 100644 spec/lib/gitlab/badge/release/metadata_spec.rb create mode 100644 spec/lib/gitlab/badge/release/template_spec.rb diff --git a/spec/lib/gitlab/badge/release/latest_release_spec.rb b/spec/lib/gitlab/badge/release/latest_release_spec.rb new file mode 100644 index 00000000000000..beb0dbe683a4f3 --- /dev/null +++ b/spec/lib/gitlab/badge/release/latest_release_spec.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Badge::Release::Latest_Release do + let(:project) { create(:project, :repository) } + let(:job_name) { nil } + + let(:badge) do + described_class.new(project, 'master', job_name) + end + + describe '#entity' do + it 'describes a release' do + expect(badge.entity).to eq 'release' + end + end + + describe '#metadata' do + it 'returns correct metadata' do + expect(badge.metadata.image_url).to include 'release.svg' + end + end + + describe '#template' do + it 'returns correct template' do + expect(badge.template.key_text).to eq 'release' + end + end + +# shared_examples 'unknown latest release' do +# context 'particular job specified' do +# let(:job_name) { '' } +# +# it 'returns nil' do +# expect(badge.status).to be_nil +# end +# end +# +# context 'particular job not specified' do +# let(:job_name) { nil } +# +# it 'returns nil' do +# expect(badge.status).to be_nil +# end +# end +# end +# +# context 'when latest successful pipeline exists' do +# before do +# create_pipeline do |pipeline| +# create(:ci_build, :success, pipeline: pipeline, name: 'first', release: 40) +# create(:ci_build, :success, pipeline: pipeline, release: 60) +# end +# +# create_pipeline do |pipeline| +# create(:ci_build, :failed, pipeline: pipeline, release: 10) +# end +# end +# +# context 'when particular job specified' do +# let(:job_name) { 'first' } +# +# it 'returns release for the particular job' do +# expect(badge.status).to eq 40 +# end +# end +# +# context 'when particular job not specified' do +# let(:job_name) { '' } +# +# it 'returns arithemetic mean for the pipeline' do +# expect(badge.status).to eq 50 +# end +# end +# end +# +# context 'when only failed pipeline exists' do +# before do +# create_pipeline do |pipeline| +# create(:ci_build, :failed, pipeline: pipeline, release: 10) +# end +# end +# +# it_behaves_like 'unknown release report' +# +# context 'particular job specified' do +# let(:job_name) { 'nonexistent' } +# +# it 'retruns nil' do +# expect(badge.status).to be_nil +# end +# end +# end +# +# context 'pipeline does not exist' do +# it_behaves_like 'unknown release report' +# end +# +# def create_pipeline +# opts = { project: project, sha: project.commit.id, ref: 'master' } +# +# create(:ci_pipeline, opts).tap do |pipeline| +# yield pipeline +# pipeline.update_status +# end +# end +# end diff --git a/spec/lib/gitlab/badge/release/metadata_spec.rb b/spec/lib/gitlab/badge/release/metadata_spec.rb new file mode 100644 index 00000000000000..8943061d126b70 --- /dev/null +++ b/spec/lib/gitlab/badge/release/metadata_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'lib/gitlab/badge/shared/metadata' + +describe Gitlab::Badge::Release::Metadata do + let(:badge) do + double(project: create(:project), ref: 'feature', job: 'test') + end + + let(:metadata) { described_class.new(badge) } + + it_behaves_like 'badge metadata' + + describe '#title' do + it 'returns latest release title' do + expect(metadata.title).to eq 'latest release' + end + end + + describe '#image_url' do + it 'returns valid url' do + expect(metadata.image_url).to include 'badges/feature/release.svg' + end + end + + describe '#link_url' do + it 'returns valid link' do + expect(metadata.link_url).to include 'releases' + end + end +end diff --git a/spec/lib/gitlab/badge/release/template_spec.rb b/spec/lib/gitlab/badge/release/template_spec.rb new file mode 100644 index 00000000000000..80814cb73d8430 --- /dev/null +++ b/spec/lib/gitlab/badge/release/template_spec.rb @@ -0,0 +1,142 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Badge::Release::Template do + let(:badge) { double(entity: 'latest release', status: "v1.2.3") } + let(:template) { described_class.new(badge) } + + describe '#key_text' do + it 'is always says latest release' do + expect(template.key_text).to eq 'latest release' + end + end + + describe '#value_text' do + context 'when coverage is known' do + it 'returns coverage percentage' do + expect(template.value_text).to eq '90.00%' + end + end + + context 'when coverage is known to many digits' do + before do + allow(badge).to receive(:status).and_return(92.349) + end + + it 'returns rounded coverage percentage' do + expect(template.value_text).to eq '92.35%' + end + end + + context 'when coverage is unknown' do + before do + allow(badge).to receive(:status).and_return(nil) + end + + it 'returns string that says coverage is unknown' do + expect(template.value_text).to eq 'unknown' + end + end + end + + describe '#key_width' do + it 'has a fixed key width' do + expect(template.key_width).to eq 62 + end + end + + describe '#value_width' do + context 'when coverage is known' do + it 'is narrower when coverage is known' do + expect(template.value_width).to eq 54 + end + end + + context 'when coverage is unknown' do + before do + allow(badge).to receive(:status).and_return(nil) + end + + it 'is wider when coverage is unknown to fit text' do + expect(template.value_width).to eq 58 + end + end + end + + describe '#key_color' do + it 'always has the same color' do + expect(template.key_color).to eq '#555' + end + end + + describe '#value_color' do + context 'when coverage is good' do + before do + allow(badge).to receive(:status).and_return(98) + end + + it 'is green' do + expect(template.value_color).to eq '#4c1' + end + end + + context 'when coverage is acceptable' do + before do + allow(badge).to receive(:status).and_return(90) + end + + it 'is green-orange' do + expect(template.value_color).to eq '#a3c51c' + end + end + + context 'when coverage is medium' do + before do + allow(badge).to receive(:status).and_return(75) + end + + it 'is orange-yellow' do + expect(template.value_color).to eq '#dfb317' + end + end + + context 'when coverage is low' do + before do + allow(badge).to receive(:status).and_return(50) + end + + it 'is red' do + expect(template.value_color).to eq '#e05d44' + end + end + + context 'when coverage is unknown' do + before do + allow(badge).to receive(:status).and_return(nil) + end + + it 'is grey' do + expect(template.value_color).to eq '#9f9f9f' + end + end + end + + describe '#width' do + context 'when coverage is known' do + it 'returns the key width plus value width' do + expect(template.width).to eq 116 + end + end + + context 'when coverage is unknown' do + before do + allow(badge).to receive(:status).and_return(nil) + end + + it 'returns key width plus wider value width' do + expect(template.width).to eq 120 + end + end + end +end -- GitLab From b949690219b5ca44d74af8ae20b6360366cd41f7 Mon Sep 17 00:00:00 2001 From: Artem Durandin Date: Tue, 12 Nov 2019 12:25:46 +0300 Subject: [PATCH 09/23] Fixed duplicated function name and removed redundant parameters. --- app/controllers/projects/badges_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb index 332fc153745a37..8e81f82b63686a 100644 --- a/app/controllers/projects/badges_controller.rb +++ b/app/controllers/projects/badges_controller.rb @@ -20,9 +20,9 @@ def coverage render_badge coverage_report end - def coverage + def release latest_release = Gitlab::Badge::Release::Latest_Release - .new(project, params[:ref], params[:job]) + .new(project, params[:ref]) render_badge latest_release end -- GitLab From 829c67db473f58c7afcc6482e0657fd13d1452e3 Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Mon, 3 Feb 2020 13:21:33 -0800 Subject: [PATCH 10/23] fix: remove comments, add author name --- changelogs/unreleased/18098-add-release-badge.yml | 2 +- lib/gitlab/badge/release/latest_release.rb | 3 --- lib/gitlab/badge/release/metadata.rb | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/changelogs/unreleased/18098-add-release-badge.yml b/changelogs/unreleased/18098-add-release-badge.yml index 41cb22e449b96f..033a21972b9023 100644 --- a/changelogs/unreleased/18098-add-release-badge.yml +++ b/changelogs/unreleased/18098-add-release-badge.yml @@ -1,5 +1,5 @@ --- title: Added "Latest Release" badge, which shows the tag and links to release merge_request: 18098 -author: +author: Jason D'Amour @jason.damour type: added diff --git a/lib/gitlab/badge/release/latest_release.rb b/lib/gitlab/badge/release/latest_release.rb index 95d9225885ba13..cbbdc2871a12be 100644 --- a/lib/gitlab/badge/release/latest_release.rb +++ b/lib/gitlab/badge/release/latest_release.rb @@ -3,9 +3,6 @@ module Gitlab module Badge module Release - ## - # Latest Release badge - # class Latest_Release < Badge::Base attr_reader :project, :ref diff --git a/lib/gitlab/badge/release/metadata.rb b/lib/gitlab/badge/release/metadata.rb index 49b81b12ad18c3..5cba7272e30463 100644 --- a/lib/gitlab/badge/release/metadata.rb +++ b/lib/gitlab/badge/release/metadata.rb @@ -3,9 +3,6 @@ module Gitlab module Badge module Release - ## - # Class that describes release badge metadata - # class Metadata < Badge::Metadata def initialize(badge) @project = badge.project -- GitLab From 11f88d38cccea3499c2b3e74d2a838ce64b45db4 Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Thu, 3 Oct 2019 12:57:20 -0600 Subject: [PATCH 11/23] initial commit --- lib/gitlab/badge/release/latestrelease.rb | 34 ++++++++++++++++++ lib/gitlab/badge/release/metadata.rb | 29 +++++++++++++++ lib/gitlab/badge/release/template.rb | 44 +++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 lib/gitlab/badge/release/latestrelease.rb create mode 100644 lib/gitlab/badge/release/metadata.rb create mode 100644 lib/gitlab/badge/release/template.rb diff --git a/lib/gitlab/badge/release/latestrelease.rb b/lib/gitlab/badge/release/latestrelease.rb new file mode 100644 index 00000000000000..542e1e309e7d5c --- /dev/null +++ b/lib/gitlab/badge/release/latestrelease.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Gitlab + module Badge + module Release + + class LatestRelease < Badge::Base + attr_reader :project, :ref + + def initialize(project, ref) + @project = project + @ref = ref + end + + def entity + 'latest release' + end + + def status + @release = @project.releases.last.tag || 'none' + end + + def metadata + @metadata ||= Release::Metadata.new(self) + end + + def template + @template ||= Release::Template.new(self) + end + + end + end + end +end diff --git a/lib/gitlab/badge/release/metadata.rb b/lib/gitlab/badge/release/metadata.rb new file mode 100644 index 00000000000000..49b81b12ad18c3 --- /dev/null +++ b/lib/gitlab/badge/release/metadata.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Gitlab + module Badge + module Release + ## + # Class that describes release badge metadata + # + class Metadata < Badge::Metadata + def initialize(badge) + @project = badge.project + @ref = badge.ref + end + + def title + 'latest release' + end + + def image_url + release_project_badges_url(@project, @ref, format: :svg) + end + + def link_url + project_release_url(@project, id: @ref) + end + end + end + end +end diff --git a/lib/gitlab/badge/release/template.rb b/lib/gitlab/badge/release/template.rb new file mode 100644 index 00000000000000..7e05fdc1e0d369 --- /dev/null +++ b/lib/gitlab/badge/release/template.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Gitlab + module Badge + module Release + ## + # Class that represents a release badge template. + # + # Template object will be passed to badge.svg.erb template. + # + class Template < Badge::Template + STATUS_COLOR = { + latest: '#4c1', + none: '#e05d44', + }.freeze + + def initialize(badge) + @entity = badge.entity + @status = badge.status + end + + def key_text + @entity.to_s + end + + def value_text + @status.to_s + end + + def key_width + 62 + end + + def value_width + 54 + end + + def value_color + STATUS_COLOR[@status.to_sym] || STATUS_COLOR[:latest] + end + end + end + end +end -- GitLab From e78416ebee9fa740bb3acc4e2e8a29e79be8c13e Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Thu, 3 Oct 2019 14:07:01 -0600 Subject: [PATCH 12/23] change latest release badge color to blue --- lib/gitlab/badge/release/template.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/badge/release/template.rb b/lib/gitlab/badge/release/template.rb index 7e05fdc1e0d369..9edbf6f5a91f55 100644 --- a/lib/gitlab/badge/release/template.rb +++ b/lib/gitlab/badge/release/template.rb @@ -10,8 +10,8 @@ module Release # class Template < Badge::Template STATUS_COLOR = { - latest: '#4c1', - none: '#e05d44', + latest: '#3076af', + none: '#e05d44' }.freeze def initialize(badge) -- GitLab From c73d8ea1e5224ad7cbea00d0be822f95bb61ee5b Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Thu, 3 Oct 2019 15:19:04 -0600 Subject: [PATCH 13/23] cleanup whitespace for static analysis --- lib/gitlab/badge/release/latestrelease.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/badge/release/latestrelease.rb b/lib/gitlab/badge/release/latestrelease.rb index 542e1e309e7d5c..b9de635775c8d9 100644 --- a/lib/gitlab/badge/release/latestrelease.rb +++ b/lib/gitlab/badge/release/latestrelease.rb @@ -3,7 +3,9 @@ module Gitlab module Badge module Release - + ## + # Latest Release badge + # class LatestRelease < Badge::Base attr_reader :project, :ref @@ -27,7 +29,6 @@ def metadata def template @template ||= Release::Template.new(self) end - end end end -- GitLab From a5933485f66ebc129a50b5eec648b7f1c8f524d7 Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Thu, 3 Oct 2019 16:39:22 -0600 Subject: [PATCH 14/23] add changelog --- changelogs/unreleased/18098-add-release-badge.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelogs/unreleased/18098-add-release-badge.yml diff --git a/changelogs/unreleased/18098-add-release-badge.yml b/changelogs/unreleased/18098-add-release-badge.yml new file mode 100644 index 00000000000000..41cb22e449b96f --- /dev/null +++ b/changelogs/unreleased/18098-add-release-badge.yml @@ -0,0 +1,5 @@ +--- +title: Added "Latest Release" badge, which shows the tag and links to release +merge_request: 18098 +author: +type: added -- GitLab From 72489b1117955f805077dfff2c0f076800feddcb Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Mon, 7 Oct 2019 11:58:30 -0700 Subject: [PATCH 15/23] rename latestrelease to latest_release --- .../badge/release/{latestrelease.rb => latest_release.rb} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename lib/gitlab/badge/release/{latestrelease.rb => latest_release.rb} (93%) diff --git a/lib/gitlab/badge/release/latestrelease.rb b/lib/gitlab/badge/release/latest_release.rb similarity index 93% rename from lib/gitlab/badge/release/latestrelease.rb rename to lib/gitlab/badge/release/latest_release.rb index b9de635775c8d9..95d9225885ba13 100644 --- a/lib/gitlab/badge/release/latestrelease.rb +++ b/lib/gitlab/badge/release/latest_release.rb @@ -6,7 +6,7 @@ module Release ## # Latest Release badge # - class LatestRelease < Badge::Base + class Latest_Release < Badge::Base attr_reader :project, :ref def initialize(project, ref) -- GitLab From cc286ad0388dd786b677bda578de85064f3f8be2 Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Mon, 7 Oct 2019 11:59:10 -0700 Subject: [PATCH 16/23] add render action and url route --- app/controllers/projects/badges_controller.rb | 7 +++++++ config/routes/project.rb | 1 + 2 files changed, 8 insertions(+) diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb index 66b51b1779060b..332fc153745a37 100644 --- a/app/controllers/projects/badges_controller.rb +++ b/app/controllers/projects/badges_controller.rb @@ -20,6 +20,13 @@ def coverage render_badge coverage_report end + def coverage + latest_release = Gitlab::Badge::Release::Latest_Release + .new(project, params[:ref], params[:job]) + + render_badge latest_release + end + private def badge_layout diff --git a/config/routes/project.rb b/config/routes/project.rb index 0812f3f7b62c87..0ca50585702582 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -606,6 +606,7 @@ get :build, to: "badges#pipeline" get :pipeline get :coverage + get :release end end end -- GitLab From 14479a55643b459d6f832b12f84bb2705c2690b5 Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Mon, 7 Oct 2019 11:59:31 -0700 Subject: [PATCH 17/23] add release badge to ci_cd controller --- app/controllers/projects/settings/ci_cd_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index cfed8727450e6d..11e689947b5edf 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -115,7 +115,8 @@ def define_badges_variables @ref = params[:ref] || @project.default_branch || 'master' @badges = [Gitlab::Badge::Pipeline::Status, - Gitlab::Badge::Coverage::Report] + Gitlab::Badge::Coverage::Report, + Gitlab::Badge::Release::Latest_Release] @badges.map! do |badge| badge.new(@project, @ref).metadata -- GitLab From 3cbcd41871744efe79320666e74c5f145b72b6bd Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Wed, 9 Oct 2019 09:30:40 -0700 Subject: [PATCH 18/23] placeholder for specs --- .../badge/release/latest_release_spec.rb | 108 +++++++++++++ .../lib/gitlab/badge/release/metadata_spec.rb | 32 ++++ .../lib/gitlab/badge/release/template_spec.rb | 142 ++++++++++++++++++ 3 files changed, 282 insertions(+) create mode 100644 spec/lib/gitlab/badge/release/latest_release_spec.rb create mode 100644 spec/lib/gitlab/badge/release/metadata_spec.rb create mode 100644 spec/lib/gitlab/badge/release/template_spec.rb diff --git a/spec/lib/gitlab/badge/release/latest_release_spec.rb b/spec/lib/gitlab/badge/release/latest_release_spec.rb new file mode 100644 index 00000000000000..beb0dbe683a4f3 --- /dev/null +++ b/spec/lib/gitlab/badge/release/latest_release_spec.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Badge::Release::Latest_Release do + let(:project) { create(:project, :repository) } + let(:job_name) { nil } + + let(:badge) do + described_class.new(project, 'master', job_name) + end + + describe '#entity' do + it 'describes a release' do + expect(badge.entity).to eq 'release' + end + end + + describe '#metadata' do + it 'returns correct metadata' do + expect(badge.metadata.image_url).to include 'release.svg' + end + end + + describe '#template' do + it 'returns correct template' do + expect(badge.template.key_text).to eq 'release' + end + end + +# shared_examples 'unknown latest release' do +# context 'particular job specified' do +# let(:job_name) { '' } +# +# it 'returns nil' do +# expect(badge.status).to be_nil +# end +# end +# +# context 'particular job not specified' do +# let(:job_name) { nil } +# +# it 'returns nil' do +# expect(badge.status).to be_nil +# end +# end +# end +# +# context 'when latest successful pipeline exists' do +# before do +# create_pipeline do |pipeline| +# create(:ci_build, :success, pipeline: pipeline, name: 'first', release: 40) +# create(:ci_build, :success, pipeline: pipeline, release: 60) +# end +# +# create_pipeline do |pipeline| +# create(:ci_build, :failed, pipeline: pipeline, release: 10) +# end +# end +# +# context 'when particular job specified' do +# let(:job_name) { 'first' } +# +# it 'returns release for the particular job' do +# expect(badge.status).to eq 40 +# end +# end +# +# context 'when particular job not specified' do +# let(:job_name) { '' } +# +# it 'returns arithemetic mean for the pipeline' do +# expect(badge.status).to eq 50 +# end +# end +# end +# +# context 'when only failed pipeline exists' do +# before do +# create_pipeline do |pipeline| +# create(:ci_build, :failed, pipeline: pipeline, release: 10) +# end +# end +# +# it_behaves_like 'unknown release report' +# +# context 'particular job specified' do +# let(:job_name) { 'nonexistent' } +# +# it 'retruns nil' do +# expect(badge.status).to be_nil +# end +# end +# end +# +# context 'pipeline does not exist' do +# it_behaves_like 'unknown release report' +# end +# +# def create_pipeline +# opts = { project: project, sha: project.commit.id, ref: 'master' } +# +# create(:ci_pipeline, opts).tap do |pipeline| +# yield pipeline +# pipeline.update_status +# end +# end +# end diff --git a/spec/lib/gitlab/badge/release/metadata_spec.rb b/spec/lib/gitlab/badge/release/metadata_spec.rb new file mode 100644 index 00000000000000..8943061d126b70 --- /dev/null +++ b/spec/lib/gitlab/badge/release/metadata_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'lib/gitlab/badge/shared/metadata' + +describe Gitlab::Badge::Release::Metadata do + let(:badge) do + double(project: create(:project), ref: 'feature', job: 'test') + end + + let(:metadata) { described_class.new(badge) } + + it_behaves_like 'badge metadata' + + describe '#title' do + it 'returns latest release title' do + expect(metadata.title).to eq 'latest release' + end + end + + describe '#image_url' do + it 'returns valid url' do + expect(metadata.image_url).to include 'badges/feature/release.svg' + end + end + + describe '#link_url' do + it 'returns valid link' do + expect(metadata.link_url).to include 'releases' + end + end +end diff --git a/spec/lib/gitlab/badge/release/template_spec.rb b/spec/lib/gitlab/badge/release/template_spec.rb new file mode 100644 index 00000000000000..80814cb73d8430 --- /dev/null +++ b/spec/lib/gitlab/badge/release/template_spec.rb @@ -0,0 +1,142 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Badge::Release::Template do + let(:badge) { double(entity: 'latest release', status: "v1.2.3") } + let(:template) { described_class.new(badge) } + + describe '#key_text' do + it 'is always says latest release' do + expect(template.key_text).to eq 'latest release' + end + end + + describe '#value_text' do + context 'when coverage is known' do + it 'returns coverage percentage' do + expect(template.value_text).to eq '90.00%' + end + end + + context 'when coverage is known to many digits' do + before do + allow(badge).to receive(:status).and_return(92.349) + end + + it 'returns rounded coverage percentage' do + expect(template.value_text).to eq '92.35%' + end + end + + context 'when coverage is unknown' do + before do + allow(badge).to receive(:status).and_return(nil) + end + + it 'returns string that says coverage is unknown' do + expect(template.value_text).to eq 'unknown' + end + end + end + + describe '#key_width' do + it 'has a fixed key width' do + expect(template.key_width).to eq 62 + end + end + + describe '#value_width' do + context 'when coverage is known' do + it 'is narrower when coverage is known' do + expect(template.value_width).to eq 54 + end + end + + context 'when coverage is unknown' do + before do + allow(badge).to receive(:status).and_return(nil) + end + + it 'is wider when coverage is unknown to fit text' do + expect(template.value_width).to eq 58 + end + end + end + + describe '#key_color' do + it 'always has the same color' do + expect(template.key_color).to eq '#555' + end + end + + describe '#value_color' do + context 'when coverage is good' do + before do + allow(badge).to receive(:status).and_return(98) + end + + it 'is green' do + expect(template.value_color).to eq '#4c1' + end + end + + context 'when coverage is acceptable' do + before do + allow(badge).to receive(:status).and_return(90) + end + + it 'is green-orange' do + expect(template.value_color).to eq '#a3c51c' + end + end + + context 'when coverage is medium' do + before do + allow(badge).to receive(:status).and_return(75) + end + + it 'is orange-yellow' do + expect(template.value_color).to eq '#dfb317' + end + end + + context 'when coverage is low' do + before do + allow(badge).to receive(:status).and_return(50) + end + + it 'is red' do + expect(template.value_color).to eq '#e05d44' + end + end + + context 'when coverage is unknown' do + before do + allow(badge).to receive(:status).and_return(nil) + end + + it 'is grey' do + expect(template.value_color).to eq '#9f9f9f' + end + end + end + + describe '#width' do + context 'when coverage is known' do + it 'returns the key width plus value width' do + expect(template.width).to eq 116 + end + end + + context 'when coverage is unknown' do + before do + allow(badge).to receive(:status).and_return(nil) + end + + it 'returns key width plus wider value width' do + expect(template.width).to eq 120 + end + end + end +end -- GitLab From 05173c1208144b3afd6f545b30eb7dbcbcaa2fb2 Mon Sep 17 00:00:00 2001 From: Artem Durandin Date: Tue, 12 Nov 2019 12:25:46 +0300 Subject: [PATCH 19/23] Fixed duplicated function name and removed redundant parameters. --- app/controllers/projects/badges_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb index 332fc153745a37..8e81f82b63686a 100644 --- a/app/controllers/projects/badges_controller.rb +++ b/app/controllers/projects/badges_controller.rb @@ -20,9 +20,9 @@ def coverage render_badge coverage_report end - def coverage + def release latest_release = Gitlab::Badge::Release::Latest_Release - .new(project, params[:ref], params[:job]) + .new(project, params[:ref]) render_badge latest_release end -- GitLab From e2c8661367280760fba271f1d1a64c8487c48dc5 Mon Sep 17 00:00:00 2001 From: Jason DAmour Date: Mon, 3 Feb 2020 13:21:33 -0800 Subject: [PATCH 20/23] fix: remove comments, add author name --- changelogs/unreleased/18098-add-release-badge.yml | 2 +- lib/gitlab/badge/release/latest_release.rb | 3 --- lib/gitlab/badge/release/metadata.rb | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/changelogs/unreleased/18098-add-release-badge.yml b/changelogs/unreleased/18098-add-release-badge.yml index 41cb22e449b96f..033a21972b9023 100644 --- a/changelogs/unreleased/18098-add-release-badge.yml +++ b/changelogs/unreleased/18098-add-release-badge.yml @@ -1,5 +1,5 @@ --- title: Added "Latest Release" badge, which shows the tag and links to release merge_request: 18098 -author: +author: Jason D'Amour @jason.damour type: added diff --git a/lib/gitlab/badge/release/latest_release.rb b/lib/gitlab/badge/release/latest_release.rb index 95d9225885ba13..cbbdc2871a12be 100644 --- a/lib/gitlab/badge/release/latest_release.rb +++ b/lib/gitlab/badge/release/latest_release.rb @@ -3,9 +3,6 @@ module Gitlab module Badge module Release - ## - # Latest Release badge - # class Latest_Release < Badge::Base attr_reader :project, :ref diff --git a/lib/gitlab/badge/release/metadata.rb b/lib/gitlab/badge/release/metadata.rb index 49b81b12ad18c3..5cba7272e30463 100644 --- a/lib/gitlab/badge/release/metadata.rb +++ b/lib/gitlab/badge/release/metadata.rb @@ -3,9 +3,6 @@ module Gitlab module Badge module Release - ## - # Class that describes release badge metadata - # class Metadata < Badge::Metadata def initialize(badge) @project = badge.project -- GitLab From 971b4a26e7d851760712f64ff50638afbd03a743 Mon Sep 17 00:00:00 2001 From: Jason D'Amour Date: Fri, 13 Nov 2020 21:59:42 +0000 Subject: [PATCH 21/23] Apply 3 suggestion(s) to 3 file(s) --- spec/lib/gitlab/badge/release/latest_release_spec.rb | 2 +- spec/lib/gitlab/badge/release/metadata_spec.rb | 2 +- spec/lib/gitlab/badge/release/template_spec.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/lib/gitlab/badge/release/latest_release_spec.rb b/spec/lib/gitlab/badge/release/latest_release_spec.rb index beb0dbe683a4f3..50795e0fdc93c5 100644 --- a/spec/lib/gitlab/badge/release/latest_release_spec.rb +++ b/spec/lib/gitlab/badge/release/latest_release_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Gitlab::Badge::Release::Latest_Release do +RSpec.describe Gitlab::Badge::Release::Latest_Release do let(:project) { create(:project, :repository) } let(:job_name) { nil } diff --git a/spec/lib/gitlab/badge/release/metadata_spec.rb b/spec/lib/gitlab/badge/release/metadata_spec.rb index 8943061d126b70..1554c22982b78f 100644 --- a/spec/lib/gitlab/badge/release/metadata_spec.rb +++ b/spec/lib/gitlab/badge/release/metadata_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require 'lib/gitlab/badge/shared/metadata' -describe Gitlab::Badge::Release::Metadata do +RSpec.describe Gitlab::Badge::Release::Metadata do let(:badge) do double(project: create(:project), ref: 'feature', job: 'test') end diff --git a/spec/lib/gitlab/badge/release/template_spec.rb b/spec/lib/gitlab/badge/release/template_spec.rb index 80814cb73d8430..41c147b6790685 100644 --- a/spec/lib/gitlab/badge/release/template_spec.rb +++ b/spec/lib/gitlab/badge/release/template_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Gitlab::Badge::Release::Template do +RSpec.describe Gitlab::Badge::Release::Template do let(:badge) { double(entity: 'latest release', status: "v1.2.3") } let(:template) { described_class.new(badge) } -- GitLab From 35cfa33c3d4ef60706d2d2f61d1722a8b3ea705d Mon Sep 17 00:00:00 2001 From: Jason D'Amour Date: Fri, 13 Nov 2020 22:20:21 +0000 Subject: [PATCH 22/23] fix: update tests to be specific to release badge --- lib/gitlab/badge/release/latest_release.rb | 2 +- lib/gitlab/badge/release/template.rb | 2 +- .../lib/gitlab/badge/release/template_spec.rb | 101 +++--------------- 3 files changed, 18 insertions(+), 87 deletions(-) diff --git a/lib/gitlab/badge/release/latest_release.rb b/lib/gitlab/badge/release/latest_release.rb index cbbdc2871a12be..066bfb26b82db7 100644 --- a/lib/gitlab/badge/release/latest_release.rb +++ b/lib/gitlab/badge/release/latest_release.rb @@ -15,7 +15,7 @@ def entity 'latest release' end - def status + def release @release = @project.releases.last.tag || 'none' end diff --git a/lib/gitlab/badge/release/template.rb b/lib/gitlab/badge/release/template.rb index 9edbf6f5a91f55..d69affc36b25b9 100644 --- a/lib/gitlab/badge/release/template.rb +++ b/lib/gitlab/badge/release/template.rb @@ -16,7 +16,7 @@ class Template < Badge::Template def initialize(badge) @entity = badge.entity - @status = badge.status + @release = badge.release end def key_text diff --git a/spec/lib/gitlab/badge/release/template_spec.rb b/spec/lib/gitlab/badge/release/template_spec.rb index 41c147b6790685..8c8a78242c43f2 100644 --- a/spec/lib/gitlab/badge/release/template_spec.rb +++ b/spec/lib/gitlab/badge/release/template_spec.rb @@ -13,29 +13,19 @@ end describe '#value_text' do - context 'when coverage is known' do - it 'returns coverage percentage' do - expect(template.value_text).to eq '90.00%' + context 'when a release exists' do + it 'returns the tag of the release' do + expect(template.value_text).to eq 'v1.2.3' end end - context 'when coverage is known to many digits' do + context 'no releases exist' do before do - allow(badge).to receive(:status).and_return(92.349) + allow(badge).to receive(:status).and_return("none") end - it 'returns rounded coverage percentage' do - expect(template.value_text).to eq '92.35%' - end - end - - context 'when coverage is unknown' do - before do - allow(badge).to receive(:status).and_return(nil) - end - - it 'returns string that says coverage is unknown' do - expect(template.value_text).to eq 'unknown' + it 'returns string that latest release is none' do + expect(template.value_text).to eq 'none' end end end @@ -47,20 +37,8 @@ end describe '#value_width' do - context 'when coverage is known' do - it 'is narrower when coverage is known' do - expect(template.value_width).to eq 54 - end - end - - context 'when coverage is unknown' do - before do - allow(badge).to receive(:status).and_return(nil) - end - - it 'is wider when coverage is unknown to fit text' do - expect(template.value_width).to eq 58 - end + it 'has a fixed value width' do + expect(template.value_width).to eq 54 end end @@ -71,72 +49,25 @@ end describe '#value_color' do - context 'when coverage is good' do - before do - allow(badge).to receive(:status).and_return(98) - end - - it 'is green' do - expect(template.value_color).to eq '#4c1' - end - end - - context 'when coverage is acceptable' do - before do - allow(badge).to receive(:status).and_return(90) - end - - it 'is green-orange' do - expect(template.value_color).to eq '#a3c51c' - end - end - - context 'when coverage is medium' do + context 'when release exists' do before do - allow(badge).to receive(:status).and_return(75) + allow(badge).to receive(:release).and_return("v1.2.3") end - it 'is orange-yellow' do - expect(template.value_color).to eq '#dfb317' - end - end - - context 'when coverage is low' do - before do - allow(badge).to receive(:status).and_return(50) - end - - it 'is red' do - expect(template.value_color).to eq '#e05d44' + it 'is blue' do + expect(template.value_color).to eq '#3076af' end end - context 'when coverage is unknown' do + context 'when release does not exist' do before do - allow(badge).to receive(:status).and_return(nil) + allow(badge).to receive(:release).and_return("none") end it 'is grey' do - expect(template.value_color).to eq '#9f9f9f' - end - end - end - - describe '#width' do - context 'when coverage is known' do - it 'returns the key width plus value width' do - expect(template.width).to eq 116 + expect(template.value_color).to eq '#e05d44' end end - context 'when coverage is unknown' do - before do - allow(badge).to receive(:status).and_return(nil) - end - - it 'returns key width plus wider value width' do - expect(template.width).to eq 120 - end - end end end -- GitLab From 072c2dec4e305dd2b4503220f72c2b22c62db950 Mon Sep 17 00:00:00 2001 From: Jason D'Amour Date: Fri, 13 Nov 2020 22:20:45 +0000 Subject: [PATCH 23/23] rename property --- spec/lib/gitlab/badge/release/template_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/lib/gitlab/badge/release/template_spec.rb b/spec/lib/gitlab/badge/release/template_spec.rb index 8c8a78242c43f2..1e8f4302ce2a8c 100644 --- a/spec/lib/gitlab/badge/release/template_spec.rb +++ b/spec/lib/gitlab/badge/release/template_spec.rb @@ -21,7 +21,7 @@ context 'no releases exist' do before do - allow(badge).to receive(:status).and_return("none") + allow(badge).to receive(:release).and_return("none") end it 'returns string that latest release is none' do -- GitLab