Commit 8eae7b10 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'feature/expose-builds-badge' into 'master'

Expose badges

This MR exposes badge somewhere in visible place.

![expose_badges](/uploads/d2e290d3013d1ef2b1bdeebbbe2c5d8b/expose_badges.png)

Closes #13801

See merge request !3326
parents d62a3dec d0bce147
...@@ -5,6 +5,7 @@ v 8.7.0 (unreleased) ...@@ -5,6 +5,7 @@ v 8.7.0 (unreleased)
- Return status code 303 after a branch DELETE operation to avoid project deletion (Stan Hu) - Return status code 303 after a branch DELETE operation to avoid project deletion (Stan Hu)
- Improved Markdown rendering performance !3389 (Yorick Peterse) - Improved Markdown rendering performance !3389 (Yorick Peterse)
- Don't attempt to look up an avatar in repo if repo directory does not exist (Stan Hu) - Don't attempt to look up an avatar in repo if repo directory does not exist (Stan Hu)
- Expose project badges in project settings
- Preserve time notes/comments have been updated at when moving issue - Preserve time notes/comments have been updated at when moving issue
- Make HTTP(s) label consistent on clone bar (Stan Hu) - Make HTTP(s) label consistent on clone bar (Stan Hu)
- Expose label description in API (Mariusz Jachimowicz) - Expose label description in API (Mariusz Jachimowicz)
......
class Projects::BadgesController < Projects::ApplicationController class Projects::BadgesController < Projects::ApplicationController
before_action :no_cache_headers layout 'project_settings'
before_action :authorize_admin_project!, only: [:index]
before_action :no_cache_headers, except: [:index]
def index
@ref = params[:ref] || @project.default_branch || 'master'
@build_badge = Gitlab::Badge::Build.new(@project, @ref)
end
def build def build
badge = Gitlab::Badge::Build.new(project, params[:ref]) badge = Gitlab::Badge::Build.new(project, params[:ref])
......
...@@ -24,6 +24,8 @@ class Projects::RefsController < Projects::ApplicationController ...@@ -24,6 +24,8 @@ class Projects::RefsController < Projects::ApplicationController
namespace_project_find_file_path(@project.namespace, @project, @id) namespace_project_find_file_path(@project.namespace, @project, @id)
when "graphs_commits" when "graphs_commits"
commits_namespace_project_graph_path(@project.namespace, @project, @id) commits_namespace_project_graph_path(@project.namespace, @project, @id)
when "badges"
namespace_project_badges_path(@project.namespace, @project, ref: @id)
else else
namespace_project_commits_path(@project.namespace, @project, @id) namespace_project_commits_path(@project.namespace, @project, @id)
end end
......
...@@ -51,8 +51,13 @@ ...@@ -51,8 +51,13 @@
= icon('code fw') = icon('code fw')
%span %span
Variables Variables
= nav_link path: 'triggers#index' do = nav_link(controller: :triggers) do
= link_to namespace_project_triggers_path(@project.namespace, @project), title: 'Triggers' do = link_to namespace_project_triggers_path(@project.namespace, @project), title: 'Triggers' do
= icon('retweet fw') = icon('retweet fw')
%span %span
Triggers Triggers
= nav_link(controller: :badges) do
= link_to namespace_project_badges_path(@project.namespace, @project), title: 'Badges' do
= icon('star-half-empty fw')
%span
Badges
- page_title 'Badges'
- badges_path = namespace_project_badges_path(@project.namespace, @project)
- header_title project_title(@project, 'Badges', badges_path)
.prepend-top-10
.panel.panel-default
.panel-heading
%b Builds badge &middot;
= @build_badge.to_html
.pull-right
= render 'shared/ref_switcher', destination: 'badges'
.panel-body
.row
.col-md-2.text-center
Markdown
.col-md-10.code.js-syntax-highlight
= highlight('.md', @build_badge.to_markdown)
.row
%hr
.row
.col-md-2.text-center
HTML
.col-md-10.code.js-syntax-highlight
= highlight('.html', @build_badge.to_html)
...@@ -750,15 +750,16 @@ Rails.application.routes.draw do ...@@ -750,15 +750,16 @@ Rails.application.routes.draw do
end end
resources :runner_projects, only: [:create, :destroy] resources :runner_projects, only: [:create, :destroy]
resources :badges, only: [], path: 'badges/*ref', resources :badges, only: [:index] do
constraints: { ref: Gitlab::Regex.git_reference_regex } do
collection do collection do
scope '*ref', constraints: { ref: Gitlab::Regex.git_reference_regex } do
get :build, constraints: { format: /svg/ } get :build, constraints: { format: /svg/ }
end end
end end
end end
end end
end end
end
# Get all keys of user # Get all keys of user
get ':username.keys' => 'profiles/keys#get_keys' , constraints: { username: /.*/ } get ':username.keys' => 'profiles/keys#get_keys' , constraints: { username: /.*/ }
......
...@@ -4,14 +4,15 @@ module Gitlab ...@@ -4,14 +4,15 @@ module Gitlab
# Build badge # Build badge
# #
class Build class Build
include Gitlab::Application.routes.url_helpers
include ActionView::Helpers::AssetTagHelper
include ActionView::Helpers::UrlHelper
def initialize(project, ref) def initialize(project, ref)
@project, @ref = project, ref
@image = ::Ci::ImageForBuildService.new.execute(project, ref: ref) @image = ::Ci::ImageForBuildService.new.execute(project, ref: ref)
end end
def to_s
@image[:name].sub(/\.svg$/, '')
end
def type def type
'image/svg+xml' 'image/svg+xml'
end end
...@@ -19,6 +20,27 @@ module Gitlab ...@@ -19,6 +20,27 @@ module Gitlab
def data def data
File.read(@image[:path]) File.read(@image[:path])
end end
def to_s
@image[:name].sub(/\.svg$/, '')
end
def to_html
link_to(image_tag(image_url, alt: 'build status'), link_url)
end
def to_markdown
"[![build status](#{image_url})](#{link_url})"
end
def image_url
build_namespace_project_badges_url(@project.namespace,
@project, @ref, format: :svg)
end
def link_url
namespace_project_commits_url(@project.namespace, @project, id: @ref)
end
end end
end end
end end
require 'spec_helper'
feature 'list of badges' do
include Select2Helper
background do
user = create(:user)
project = create(:project)
project.team << [user, :master]
login_as(user)
visit edit_namespace_project_path(project.namespace, project)
end
scenario 'user displays list of badges' do
click_link 'Badges'
expect(page).to have_content 'build status'
expect(page).to have_content 'Markdown'
expect(page).to have_content 'HTML'
expect(page).to have_css('.highlight', count: 2)
expect(page).to have_xpath("//img[@alt='build status']")
page.within('.highlight', match: :first) do
expect(page).to have_content 'badges/master/build.svg'
end
end
scenario 'user changes current ref on badges list page', js: true do
click_link 'Badges'
select2('improve/awesome', from: '#ref')
expect(page).to have_content 'badges/improve/awesome/build.svg'
end
end
...@@ -3,13 +3,44 @@ require 'spec_helper' ...@@ -3,13 +3,44 @@ require 'spec_helper'
describe Gitlab::Badge::Build do describe Gitlab::Badge::Build do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:sha) { project.commit.sha } let(:sha) { project.commit.sha }
let(:badge) { described_class.new(project, 'master') } let(:branch) { 'master' }
let(:badge) { described_class.new(project, branch) }
describe '#type' do describe '#type' do
subject { badge.type } subject { badge.type }
it { is_expected.to eq 'image/svg+xml' } it { is_expected.to eq 'image/svg+xml' }
end end
describe '#to_html' do
let(:html) { Nokogiri::HTML.parse(badge.to_html) }
let(:a_href) { html.at('a') }
it 'points to link' do
expect(a_href[:href]).to eq badge.link_url
end
it 'contains clickable image' do
expect(a_href.children.first.name).to eq 'img'
end
end
describe '#to_markdown' do
subject { badge.to_markdown }
it { is_expected.to include badge.image_url }
it { is_expected.to include badge.link_url }
end
describe '#image_url' do
subject { badge.image_url }
it { is_expected.to include "badges/#{branch}/build.svg" }
end
describe '#link_url' do
subject { badge.link_url }
it { is_expected.to include "commits/#{branch}" }
end
context 'build exists' do context 'build exists' do
let(:ci_commit) { create(:ci_commit, project: project, sha: sha) } let(:ci_commit) { create(:ci_commit, project: project, sha: sha) }
let!(:build) { create(:ci_build, commit: ci_commit) } let!(:build) { create(:ci_build, commit: ci_commit) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment