From ca018156107037b6cb7ee5ce1ae4ed6bff394408 Mon Sep 17 00:00:00 2001 From: TamsilAmani Date: Sun, 19 May 2024 21:43:25 +0530 Subject: [PATCH 1/5] Add support for latest_tag This will add support for using latest_tag for a project's badge link and url. It will pick the latest tag added to the respository if any. Refactored some tests too. Changelog: added --- app/assets/javascripts/badges/constants.js | 1 + app/models/badge.rb | 5 ++++- doc/api/group_badges.md | 1 + doc/api/project_badges.md | 1 + doc/user/project/badges.md | 1 + spec/models/badge_spec.rb | 22 ++++++++++++---------- 6 files changed, 20 insertions(+), 11 deletions(-) diff --git a/app/assets/javascripts/badges/constants.js b/app/assets/javascripts/badges/constants.js index 56b45abbe6bf07..e98df2e5971057 100644 --- a/app/assets/javascripts/badges/constants.js +++ b/app/assets/javascripts/badges/constants.js @@ -7,6 +7,7 @@ export const PLACEHOLDERS = [ 'project_id', 'default_branch', 'commit_sha', + 'latest_tag', ]; export const INITIAL_PAGE = 1; export const PAGE_SIZE = 10; diff --git a/app/models/badge.rb b/app/models/badge.rb index f4e719887ba058..2c07751a3ef150 100644 --- a/app/models/badge.rb +++ b/app/models/badge.rb @@ -12,7 +12,10 @@ class Badge < ApplicationRecord 'project_name' => :path, 'project_id' => :id, 'default_branch' => :default_branch, - 'commit_sha' => ->(project) { project.commit&.sha } + 'commit_sha' => ->(project) { project.commit&.sha }, + 'latest_tag' => ->(project) do + TagsFinder.new(project.repository, per_page: 1, sort: 'updated_desc').execute.first&.name if project.repository + end }.freeze # This regex is built dynamically using the keys from the PLACEHOLDER struct. diff --git a/doc/api/group_badges.md b/doc/api/group_badges.md index 52ed529682d9ef..ac7b825dbb0dc1 100644 --- a/doc/api/group_badges.md +++ b/doc/api/group_badges.md @@ -22,6 +22,7 @@ DETAILS: - **%{project_id}**: replaced by the project ID. - **%{default_branch}**: replaced by the project default branch. - **%{commit_sha}**: replaced by the last project's commit SHA. +- **%{latest_tag}**: replaced by the last project's tag. diff --git a/doc/api/project_badges.md b/doc/api/project_badges.md index 9787decbda019e..4dc325a37f4d8c 100644 --- a/doc/api/project_badges.md +++ b/doc/api/project_badges.md @@ -22,6 +22,7 @@ DETAILS: - **%{project_id}**: Replaced by the project ID. - **%{default_branch}**: Replaced by the project default branch. - **%{commit_sha}**: Replaced by the last project's commit SHA. +- **%{latest_tag}**: Replaced by the last project's tag. diff --git a/doc/user/project/badges.md b/doc/user/project/badges.md index dd257732fe8e59..f1646c9911ed7b 100644 --- a/doc/user/project/badges.md +++ b/doc/user/project/badges.md @@ -301,6 +301,7 @@ The following placeholders are available: - `%{default_branch}`: Default branch name configured for a project's repository - `%{commit_sha}`: ID of the most recent commit to the default branch of a project's repository +- `%{latest_tag}`: Latest tag added to the project's repository NOTE: Placeholders allow badges to expose otherwise-private information, such as the diff --git a/spec/models/badge_spec.rb b/spec/models/badge_spec.rb index 79a716c2087ceb..edf5e79c4f234c 100644 --- a/spec/models/badge_spec.rb +++ b/spec/models/badge_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Badge do - let(:placeholder_url) { 'http://www.example.com/%{project_path}/%{project_id}/%{project_name}/%{default_branch}/%{commit_sha}/%{project_title}' } + let(:placeholder_url) { 'http://www.example.com/%{project_path}/%{project_id}/%{project_name}/%{default_branch}/%{commit_sha}/%{project_title}/%{latest_tag}' } describe 'validations' do # Requires the let variable url_sym @@ -61,25 +61,27 @@ end shared_examples 'rendered_links' do + let_it_be(:full_path) { project.full_path } + let_it_be(:id) { project.id } + let_it_be(:path) { project.path } + let_it_be(:title) { project.title } + let_it_be(:path) { project.path } + let_it_be(:default_branch) { 'master' } + let_it_be(:tag) { 'v1.1.1' } + let_it_be(:commit_sha) { project.commit.sha } it 'uses the project information to populate the url placeholders' do - stub_project_commit_info(project) - - expect(badge.public_send("rendered_#{method}", project)).to eq "http://www.example.com/#{project.full_path}/#{project.id}/#{project.path}/master/whatever/#{project.title}" + url = "http://www.example.com/#{full_path}/#{id}/#{path}/#{default_branch}/#{commit_sha}/#{title}/#{tag}" + expect(badge.public_send("rendered_#{method}", project)).to eq(url) end it 'returns the url if the project used is nil' do expect(badge.public_send("rendered_#{method}", nil)).to eq placeholder_url end - - def stub_project_commit_info(project) - allow(project).to receive(:commit).and_return(double('Commit', sha: 'whatever')) - allow(project).to receive(:default_branch).and_return('master') - end end context 'methods' do let(:badge) { build(:badge, link_url: placeholder_url, image_url: placeholder_url) } - let!(:project) { create(:project) } + let_it_be(:project) { create(:project, :repository) } describe '#rendered_link_url' do let(:method) { :link_url } -- GitLab From 88763227c45e8f6a6ac5c396ae6e31b028ec8c17 Mon Sep 17 00:00:00 2001 From: TamsilAmani Date: Sun, 26 May 2024 20:35:15 +0530 Subject: [PATCH 2/5] Fix formatting and add specs --- doc/api/group_badges.md | 4 ++-- doc/api/project_badges.md | 4 ++-- spec/models/badge_spec.rb | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/doc/api/group_badges.md b/doc/api/group_badges.md index ac7b825dbb0dc1..53f6936665524c 100644 --- a/doc/api/group_badges.md +++ b/doc/api/group_badges.md @@ -21,8 +21,8 @@ DETAILS: - **%{project_name}**: replaced by the project name. - **%{project_id}**: replaced by the project ID. - **%{default_branch}**: replaced by the project default branch. -- **%{commit_sha}**: replaced by the last project's commit SHA. -- **%{latest_tag}**: replaced by the last project's tag. +- **%{commit_sha}**: replaced by the project's last commit SHA. +- **%{latest_tag}**: replaced by the project's last tag. diff --git a/doc/api/project_badges.md b/doc/api/project_badges.md index 4dc325a37f4d8c..93f916d4fde5c0 100644 --- a/doc/api/project_badges.md +++ b/doc/api/project_badges.md @@ -21,8 +21,8 @@ DETAILS: - **%{project_name}**: Replaced by the project name. - **%{project_id}**: Replaced by the project ID. - **%{default_branch}**: Replaced by the project default branch. -- **%{commit_sha}**: Replaced by the last project's commit SHA. -- **%{latest_tag}**: Replaced by the last project's tag. +- **%{commit_sha}**: Replaced by the project's last commit SHA. +- **%{latest_tag}**: Replaced by the project's last tag. diff --git a/spec/models/badge_spec.rb b/spec/models/badge_spec.rb index edf5e79c4f234c..ba88ff778c187b 100644 --- a/spec/models/badge_spec.rb +++ b/spec/models/badge_spec.rb @@ -69,6 +69,7 @@ let_it_be(:default_branch) { 'master' } let_it_be(:tag) { 'v1.1.1' } let_it_be(:commit_sha) { project.commit.sha } + it 'uses the project information to populate the url placeholders' do url = "http://www.example.com/#{full_path}/#{id}/#{path}/#{default_branch}/#{commit_sha}/#{title}/#{tag}" expect(badge.public_send("rendered_#{method}", project)).to eq(url) @@ -77,11 +78,28 @@ it 'returns the url if the project used is nil' do expect(badge.public_send("rendered_#{method}", nil)).to eq placeholder_url end + + let_it_be(:full_path_empty_repo) { project_empty_repository.full_path } + let_it_be(:id_empty_repo) { project_empty_repository.id } + let_it_be(:path_empty_repo) { project_empty_repository.path } + let_it_be(:title_empty_repo) { project_empty_repository.title } + # Using constant values for the placeholders which won't be populated in the placeholder_url as there is no repo. + let_it_be(:default_branch_empty_repo) { '%{default_branch}' } + let_it_be(:tag_empty_repo) { '%{latest_tag}' } + let_it_be(:commit_sha_empty_repo) { '%{commit_sha}' } + + it 'populate the placeholders when repository is null' do + url = "http://www.example.com/#{full_path_empty_repo}/#{id_empty_repo}/#{path_empty_repo}/" \ + "#{default_branch_empty_repo}/#{commit_sha_empty_repo}/#{title_empty_repo}/#{tag_empty_repo}" + + expect(badge.public_send("rendered_#{method}", project_empty_repository)).to eq(url) + end end context 'methods' do let(:badge) { build(:badge, link_url: placeholder_url, image_url: placeholder_url) } let_it_be(:project) { create(:project, :repository) } + let_it_be(:project_empty_repository) { create(:project, :empty_repo) } describe '#rendered_link_url' do let(:method) { :link_url } -- GitLab From eceee540c22df014ef6cc491b9fa0f7598da2670 Mon Sep 17 00:00:00 2001 From: TamsilAmani Date: Sun, 26 May 2024 20:56:08 +0530 Subject: [PATCH 3/5] Remove duplicate variable --- spec/models/badge_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/models/badge_spec.rb b/spec/models/badge_spec.rb index ba88ff778c187b..8bc6b7e442189c 100644 --- a/spec/models/badge_spec.rb +++ b/spec/models/badge_spec.rb @@ -65,7 +65,6 @@ let_it_be(:id) { project.id } let_it_be(:path) { project.path } let_it_be(:title) { project.title } - let_it_be(:path) { project.path } let_it_be(:default_branch) { 'master' } let_it_be(:tag) { 'v1.1.1' } let_it_be(:commit_sha) { project.commit.sha } -- GitLab From 55c34a72f03d139900a101afe415828ef10f9ff3 Mon Sep 17 00:00:00 2001 From: TamsilAmani Date: Wed, 29 May 2024 22:59:22 +0530 Subject: [PATCH 4/5] Add context for nil and non-nil repository --- spec/models/badge_spec.rb | 60 +++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/spec/models/badge_spec.rb b/spec/models/badge_spec.rb index 8bc6b7e442189c..c2bd880eb9755b 100644 --- a/spec/models/badge_spec.rb +++ b/spec/models/badge_spec.rb @@ -61,37 +61,41 @@ end shared_examples 'rendered_links' do - let_it_be(:full_path) { project.full_path } - let_it_be(:id) { project.id } - let_it_be(:path) { project.path } - let_it_be(:title) { project.title } - let_it_be(:default_branch) { 'master' } - let_it_be(:tag) { 'v1.1.1' } - let_it_be(:commit_sha) { project.commit.sha } - - it 'uses the project information to populate the url placeholders' do - url = "http://www.example.com/#{full_path}/#{id}/#{path}/#{default_branch}/#{commit_sha}/#{title}/#{tag}" - expect(badge.public_send("rendered_#{method}", project)).to eq(url) - end + context 'when the repository is not nil' do + let_it_be(:full_path) { project.full_path } + let_it_be(:id) { project.id } + let_it_be(:path) { project.path } + let_it_be(:title) { project.title } + let_it_be(:default_branch) { 'master' } + let_it_be(:tag) { 'v1.1.1' } + let_it_be(:commit_sha) { project.commit.sha } + + it 'uses the project information to populate the url placeholders' do + url = "http://www.example.com/#{full_path}/#{id}/#{path}/#{default_branch}/#{commit_sha}/#{title}/#{tag}" + expect(badge.public_send("rendered_#{method}", project)).to eq(url) + end - it 'returns the url if the project used is nil' do - expect(badge.public_send("rendered_#{method}", nil)).to eq placeholder_url + it 'returns the url if the project used is nil' do + expect(badge.public_send("rendered_#{method}", nil)).to eq placeholder_url + end end - let_it_be(:full_path_empty_repo) { project_empty_repository.full_path } - let_it_be(:id_empty_repo) { project_empty_repository.id } - let_it_be(:path_empty_repo) { project_empty_repository.path } - let_it_be(:title_empty_repo) { project_empty_repository.title } - # Using constant values for the placeholders which won't be populated in the placeholder_url as there is no repo. - let_it_be(:default_branch_empty_repo) { '%{default_branch}' } - let_it_be(:tag_empty_repo) { '%{latest_tag}' } - let_it_be(:commit_sha_empty_repo) { '%{commit_sha}' } - - it 'populate the placeholders when repository is null' do - url = "http://www.example.com/#{full_path_empty_repo}/#{id_empty_repo}/#{path_empty_repo}/" \ - "#{default_branch_empty_repo}/#{commit_sha_empty_repo}/#{title_empty_repo}/#{tag_empty_repo}" - - expect(badge.public_send("rendered_#{method}", project_empty_repository)).to eq(url) + context 'when the repository is nil' do + let_it_be(:full_path_empty_repo) { project_empty_repository.full_path } + let_it_be(:id_empty_repo) { project_empty_repository.id } + let_it_be(:path_empty_repo) { project_empty_repository.path } + let_it_be(:title_empty_repo) { project_empty_repository.title } + # Using constant values for the placeholders which won't be populated in the placeholder_url as there is no repo. + let_it_be(:default_branch_empty_repo) { '%{default_branch}' } + let_it_be(:tag_empty_repo) { '%{latest_tag}' } + let_it_be(:commit_sha_empty_repo) { '%{commit_sha}' } + + it 'populate the placeholders' do + url = "http://www.example.com/#{full_path_empty_repo}/#{id_empty_repo}/#{path_empty_repo}/" \ + "#{default_branch_empty_repo}/#{commit_sha_empty_repo}/#{title_empty_repo}/#{tag_empty_repo}" + + expect(badge.public_send("rendered_#{method}", project_empty_repository)).to eq(url) + end end end -- GitLab From 04c87a4ed59970f34e7531fc09ab7aaa8c71855e Mon Sep 17 00:00:00 2001 From: TamsilAmani Date: Sun, 2 Jun 2024 00:05:21 +0530 Subject: [PATCH 5/5] Fix rubocop lint issue --- spec/models/badge_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/badge_spec.rb b/spec/models/badge_spec.rb index c2bd880eb9755b..188c5a78e09b0b 100644 --- a/spec/models/badge_spec.rb +++ b/spec/models/badge_spec.rb @@ -92,7 +92,7 @@ it 'populate the placeholders' do url = "http://www.example.com/#{full_path_empty_repo}/#{id_empty_repo}/#{path_empty_repo}/" \ - "#{default_branch_empty_repo}/#{commit_sha_empty_repo}/#{title_empty_repo}/#{tag_empty_repo}" + "#{default_branch_empty_repo}/#{commit_sha_empty_repo}/#{title_empty_repo}/#{tag_empty_repo}" expect(badge.public_send("rendered_#{method}", project_empty_repository)).to eq(url) end -- GitLab