Commit 4eaa6a4c authored by Kamil Trzciński's avatar Kamil Trzciński

Merge branch 'fix/ci-build-status-badge' into 'master'

Fix CI build status badge

Closes #5570, #4935, #4163

See merge request !2704
parents 9bcc9ec1 9e619048
...@@ -48,6 +48,7 @@ v 8.5.0 (unreleased) ...@@ -48,6 +48,7 @@ v 8.5.0 (unreleased)
- Title for milestones should be unique (Zeger-Jan van de Weg) - Title for milestones should be unique (Zeger-Jan van de Weg)
- Validate correctness of maximum attachment size application setting - Validate correctness of maximum attachment size application setting
- Replaces "Create merge request" link with one to the "Merge Request" when one exists - Replaces "Create merge request" link with one to the "Merge Request" when one exists
- Fix CI builds badge, add a new link to builds badge, deprecate the old one
v 8.4.4 v 8.4.4
- Update omniauth-saml gem to 1.4.2 - Update omniauth-saml gem to 1.4.2
......
...@@ -12,9 +12,13 @@ module Ci ...@@ -12,9 +12,13 @@ module Ci
# Project status badge # Project status badge
# Image with build status for sha or ref # Image with build status for sha or ref
#
# This action in DEPRECATED, this is here only for backwards compatibility
# with projects migrated from GitLab CI.
#
def badge def badge
return render_404 unless @project
image = Ci::ImageForBuildService.new.execute(@project, params) image = Ci::ImageForBuildService.new.execute(@project, params)
send_file image.path, filename: image.name, disposition: 'inline', type:"image/svg+xml" send_file image.path, filename: image.name, disposition: 'inline', type:"image/svg+xml"
end end
......
class Projects::BadgesController < Projects::ApplicationController
def build
respond_to do |format|
format.html { render_404 }
format.svg do
image = Ci::ImageForBuildService.new.execute(project, ref: params[:ref])
send_file(image.path, filename: image.name, disposition: 'inline', type: 'image/svg+xml')
end
end
end
end
class Projects::BuildsController < Projects::ApplicationController class Projects::BuildsController < Projects::ApplicationController
before_action :build, except: [:index, :cancel_all] before_action :build, except: [:index, :cancel_all]
before_action :authorize_read_build!, except: [:cancel, :cancel_all, :retry] before_action :authorize_read_build!, except: [:cancel, :cancel_all, :retry]
before_action :authorize_update_build!, except: [:index, :show, :status] before_action :authorize_update_build!, except: [:index, :show, :status]
layout 'project'
layout "project"
def index def index
@scope = params[:scope] @scope = params[:scope]
...@@ -24,7 +22,6 @@ class Projects::BuildsController < Projects::ApplicationController ...@@ -24,7 +22,6 @@ class Projects::BuildsController < Projects::ApplicationController
def cancel_all def cancel_all
@project.builds.running_or_pending.each(&:cancel) @project.builds.running_or_pending.each(&:cancel)
redirect_to namespace_project_builds_path(project.namespace, project) redirect_to namespace_project_builds_path(project.namespace, project)
end end
...@@ -47,20 +44,18 @@ class Projects::BuildsController < Projects::ApplicationController ...@@ -47,20 +44,18 @@ class Projects::BuildsController < Projects::ApplicationController
end end
build = Ci::Build.retry(@build) build = Ci::Build.retry(@build)
redirect_to build_path(build) redirect_to build_path(build)
end end
def status
render json: @build.to_json(only: [:status, :id, :sha, :coverage], methods: :sha)
end
def cancel def cancel
@build.cancel @build.cancel
redirect_to build_path(@build) redirect_to build_path(@build)
end end
def status
render json: @build.to_json(only: [:status, :id, :sha, :coverage], methods: :sha)
end
private private
def build def build
......
module Ci module Ci
class ImageForBuildService class ImageForBuildService
def execute(project, params) def execute(project, opts)
sha = params[:sha] sha = opts[:sha] || ref_sha(project, opts[:ref])
sha ||=
if params[:ref]
project.commit(params[:ref]).try(:sha)
end
commit = project.ci_commits.ordered.find_by(sha: sha) commit = project.ci_commits.ordered.find_by(sha: sha)
image_name = image_for_commit(commit) image_name = image_for_commit(commit)
image_path = Rails.root.join('public/ci', image_name) image_path = Rails.root.join('public/ci', image_name)
OpenStruct.new(path: image_path, name: image_name)
OpenStruct.new(
path: image_path,
name: image_name
)
end end
private private
def ref_sha(project, ref)
project.commit(ref).try(:sha) if ref
end
def image_for_commit(commit) def image_for_commit(commit)
return 'build-unknown.svg' unless commit return 'build-unknown.svg' unless commit
'build-' + commit.status + ".svg" 'build-' + commit.status + ".svg"
end end
end end
......
...@@ -608,7 +608,7 @@ Rails.application.routes.draw do ...@@ -608,7 +608,7 @@ Rails.application.routes.draw do
resource :variables, only: [:show, :update] resource :variables, only: [:show, :update]
resources :triggers, only: [:index, :create, :destroy] resources :triggers, only: [:index, :create, :destroy]
resources :builds, only: [:index, :show] do resources :builds, only: [:index, :show], constraints: { id: /\d+/ } do
collection do collection do
post :cancel_all post :cancel_all
end end
...@@ -697,6 +697,12 @@ Rails.application.routes.draw do ...@@ -697,6 +697,12 @@ 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',
constraints: { ref: Gitlab::Regex.git_reference_regex } do
collection do
get :build, constraints: { format: /svg/ }
end
end
end end
end end
end end
......
class Gitlab::Seeder::Builds class Gitlab::Seeder::Builds
BUILD_STATUSES = %w(running pending success failed canceled)
def initialize(project) def initialize(project)
@project = project @project = project
end end
def seed! def seed!
ci_commits.each do |ci_commit| ci_commits.each do |ci_commit|
build = Ci::Build.new(build_attributes_for(ci_commit))
artifacts_cache_file(artifacts_archive_path) do |file|
build.artifacts_file = file
end
artifacts_cache_file(artifacts_metadata_path) do |file|
build.artifacts_metadata = file
end
begin begin
build.save! build_create!(ci_commit, name: 'test build 1')
build_create!(ci_commit, status: 'success', name: 'test build 2')
print '.' print '.'
rescue ActiveRecord::RecordInvalid rescue ActiveRecord::RecordInvalid
print 'F' print 'F'
...@@ -36,6 +25,28 @@ class Gitlab::Seeder::Builds ...@@ -36,6 +25,28 @@ class Gitlab::Seeder::Builds
[] []
end end
def build_create!(ci_commit, opts = {})
attributes = build_attributes_for(ci_commit).merge(opts)
build = Ci::Build.new(attributes)
if %w(success failed).include?(build.status)
artifacts_cache_file(artifacts_archive_path) do |file|
build.artifacts_file = file
end
artifacts_cache_file(artifacts_metadata_path) do |file|
build.artifacts_metadata = file
end
end
build.save!
if %w(running success failed).include?(build.status)
# We need to set build trace after saving a build (id required)
build.trace = FFaker::Lorem.paragraphs(6).join("\n\n")
end
end
def build_attributes_for(ci_commit) def build_attributes_for(ci_commit)
{ name: 'test build', commands: "$ build command", { name: 'test build', commands: "$ build command",
stage: 'test', stage_idx: 1, ref: 'master', stage: 'test', stage_idx: 1, ref: 'master',
...@@ -49,7 +60,7 @@ class Gitlab::Seeder::Builds ...@@ -49,7 +60,7 @@ class Gitlab::Seeder::Builds
end end
def build_status def build_status
BUILD_STATUSES.sample Ci::Build::AVAILABLE_STATUSES.sample
end end
def artifacts_archive_path def artifacts_archive_path
......
...@@ -184,6 +184,14 @@ you expected. ...@@ -184,6 +184,14 @@ you expected.
You are also able to view the status of any commit in the various pages in You are also able to view the status of any commit in the various pages in
GitLab, such as **Commits** and **Merge Requests**. GitLab, such as **Commits** and **Merge Requests**.
## Builds badge
You can access a builds badge image using following link:
```
http://example.gitlab.com/namespace/project/badges/branch/build.svg
```
## Next steps ## Next steps
Awesome! You started using CI in GitLab! Awesome! You started using CI in GitLab!
......
Feature: Project Badges Build
Background:
Given I sign in as a user
And I own a project
And project has CI enabled
And project has a recent build
Scenario: I want to see a badge for successfully built project
Given recent build is successful
When I display builds badge for a master branch
Then I should see a build success badge
Scenario: I want to see a badge for project with failed builds
Given recent build failed
When I display builds badge for a master branch
Then I should see a build failed badge
Scenario: I want to see a badge for project with running builds
Given recent build is successful
And project has another build that is running
When I display builds badge for a master branch
Then I should see a build running badge
class Spinach::Features::ProjectBadgesBuild < Spinach::FeatureSteps
include SharedAuthentication
include SharedProject
include SharedBuilds
include RepoHelpers
step 'I display builds badge for a master branch' do
visit build_namespace_project_badges_path(@project.namespace, @project, ref: :master, format: :svg)
end
step 'I should see a build success badge' do
expect_badge('success')
end
step 'I should see a build failed badge' do
expect_badge('failed')
end
step 'I should see a build running badge' do
expect_badge('running')
end
def expect_badge(status)
svg = Nokogiri::XML.parse(page.body)
expect(page.response_headers).to include('Content-Type' => 'image/svg+xml')
expect(svg.at(%Q{text:contains("#{status}")})).to be_truthy
end
end
...@@ -6,8 +6,20 @@ module SharedBuilds ...@@ -6,8 +6,20 @@ module SharedBuilds
end end
step 'project has a recent build' do step 'project has a recent build' do
ci_commit = create :ci_commit, project: @project, sha: sample_commit.id @ci_commit = create(:ci_commit, project: @project, sha: @project.commit.sha)
@build = create :ci_build, commit: ci_commit @build = create(:ci_build, commit: @ci_commit)
end
step 'recent build is successful' do
@build.update_column(:status, 'success')
end
step 'recent build failed' do
@build.update_column(:status, 'failed')
end
step 'project has another build that is running' do
create(:ci_build, commit: @ci_commit, name: 'second build', status: 'running')
end end
step 'I visit recent build details page' do step 'I visit recent build details page' do
......
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