Skip to content
Snippets Groups Projects
Commit a957eca6 authored by Kamil Trzcińśki's avatar Kamil Trzcińśki
Browse files

Added builds view

parent 2d0fcb4d
No related branches found
No related tags found
No related merge requests found
Showing
with 222 additions and 7 deletions
Loading
Loading
@@ -17,6 +17,7 @@ v 8.1.0 (unreleased)
- Fix cases where Markdown did not render links in activity feed (Stan Hu)
- Add first and last to pagination (Zeger-Jan van de Weg)
- Added Commit Status API
- Added Builds View
- Show CI status on commit page
- Show CI status on Your projects page and Starred projects page
- Remove "Continuous Integration" page from dashboard
Loading
Loading
Loading
Loading
@@ -7,6 +7,7 @@ class @ShortcutsNavigation extends Shortcuts
Mousetrap.bind('g e', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-project-activity'))
Mousetrap.bind('g f', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-tree'))
Mousetrap.bind('g c', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-commits'))
Mousetrap.bind('g b', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-builds'))
Mousetrap.bind('g n', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-network'))
Mousetrap.bind('g g', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-graphs'))
Mousetrap.bind('g i', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-issues'))
Loading
Loading
class Projects::BuildsController < Projects::ApplicationController
before_action :ci_project
before_action :build
before_action :build, except: [:index, :cancel_all]
 
before_action :authorize_admin_project!, except: [:show, :status]
before_action :authorize_admin_project!, except: [:index, :show, :status]
 
layout "project"
 
def index
@scope = params[:scope]
@all_builds = project.ci_builds.order('created_at DESC').page(params[:page]).per(30)
@builds =
case @scope
when 'pending'
@all_builds.pending
when 'running'
@all_builds.running
else
@all_builds
end
end
def cancel_all
@project.ci_builds.running_or_pending.each(&:cancel)
redirect_to namespace_project_builds_path(project.namespace, project)
end
def show
@builds = @ci_project.commits.find_by_sha(@build.sha).builds.order('id DESC')
@builds = @builds.where("id not in (?)", @build.id).page(params[:page]).per(20)
Loading
Loading
Loading
Loading
@@ -25,6 +25,10 @@ module GitlabRoutingHelper
namespace_project_commits_path(project.namespace, project, @ref || project.repository.root_ref)
end
 
def project_builds_path(project, *args)
namespace_project_builds_path(project.namespace, project, *args)
end
def activity_project_path(project, *args)
activity_namespace_project_path(project.namespace, project, *args)
end
Loading
Loading
Loading
Loading
@@ -113,6 +113,10 @@ module ProjectsHelper
nav_tabs << :merge_requests
end
 
if can?(current_user, :read_build, project)
nav_tabs << :builds
end
if can?(current_user, :admin_project, project)
nav_tabs << :settings
end
Loading
Loading
Loading
Loading
@@ -17,4 +17,17 @@ module RunnersHelper
class: "fa fa-circle runner-status-#{status}",
title: "Runner is #{status}, last contact was #{time_ago_in_words(runner.contacted_at)} ago"
end
def runner_link(runner)
display_name = truncate(runner.display_name, length: 20)
id = "\##{runner.id}"
if current_user && current_user.admin
link_to ci_admin_runner_path(runner) do
display_name + id
end
else
display_name + id
end
end
end
Loading
Loading
@@ -41,6 +41,7 @@ class Ability
:read_project_member,
:read_merge_request,
:read_note,
:read_build,
:download_code
]
 
Loading
Loading
@@ -127,6 +128,7 @@ class Ability
:read_project_member,
:read_merge_request,
:read_note,
:read_build,
:create_project,
:create_issue,
:create_note
Loading
Loading
Loading
Loading
@@ -56,7 +56,7 @@ module Ci
end
 
def display_name
return token unless !description.blank?
return short_sha unless !description.blank?
 
description
end
Loading
Loading
@@ -78,7 +78,7 @@ module Ci
end
 
def short_sha
token[0...10]
token[0...8]
end
end
end
Loading
Loading
@@ -99,6 +99,12 @@
.key c
%td
Go to commits
%tr
%td.shortcut
.key g
.key b
%td
Go to builds
%tr
%td.shortcut
.key g
Loading
Loading
Loading
Loading
@@ -32,12 +32,19 @@
Files
 
- if project_nav_tab? :commits
= nav_link(controller: %w(commit commits compare repositories tags branches builds)) do
= nav_link(controller: %w(commit commits compare repositories tags branches)) do
= link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits', data: {placement: 'right'} do
= icon('history fw')
%span
Commits
 
- if project_nav_tab? :builds
= nav_link(controller: %w(builds)) do
= link_to project_builds_path(@project), title: 'Builds', class: 'shortcuts-builds', data: {placement: 'right'} do
= icon('link fw')
%span
Builds
- if project_nav_tab? :network
= nav_link(controller: %w(network)) do
= link_to namespace_project_network_path(@project.namespace, @project, current_ref), title: 'Network', class: 'shortcuts-network', data: {placement: 'right'} do
Loading
Loading
Loading
Loading
@@ -66,7 +66,7 @@
%span
CI Services
= nav_link path: 'events#index' do
= link_to ci_project_events_path(@project.gitlab_ci_project) do
= link_to ci_project_events_path(@project.ensure_gitlab_ci_project) do
= icon('book fw')
%span
CI Events
%tr.build
%td.status
= ci_status_with_icon(build.status)
%td.commit_status-link
- if build.target_url
= link_to build.target_url do
%strong Build ##{build.id}
- else
%strong Build ##{build.id}
%td
= link_to namespace_project_commit_path(@project.namespace, @project, build.sha) do
= build.short_sha
%td
= link_to namespace_project_commits_path(@project.namespace, @project, build.ref) do
= build.ref
%td
- if build.runner
= runner_link(build.runner)
- else
.light none
%td
= build.name
.pull-right
- if build.tags.any?
- build.tags.each do |tag|
%span.label.label-primary
= tag
- if build.try(:trigger_request)
%span.label.label-info triggered
- if build.try(:allow_failure)
%span.label.label-danger allowed to fail
%td.duration
- if build.duration
#{duration_in_words(build.finished_at, build.started_at)}
%td.timestamp
- if build.finished_at
%span #{time_ago_in_words build.finished_at} ago
%td
.pull-right
- if current_user && can?(current_user, :manage_builds, @project)
- if build.cancel_url
= link_to build.cancel_url, title: 'Cancel' do
%i.fa.fa-remove.cred
- page_title "Builds"
- header_title project_title(@project, "Builds", project_builds_path(@project))
%ul.center-top-menu
%li{class: ('active' if @scope.nil?)}
= link_to project_builds_path(@project) do
All builds
%span.badge.js-totalbuilds-count= @all_builds.size
%li{class: ('active' if @scope == 'pending')}
= link_to project_builds_path(@project, scope: :pending) do
Pending
%span.badge.js-pending-count= @all_builds.pending.size
%li{class: ('active' if @scope == 'running')}
= link_to project_builds_path(@project, scope: :running) do
Running
%span.badge.js-running-count= @all_builds.running.size
.gray-content-block
.oneline
List of all builds from this project
- if @ci_project && current_user && can?(current_user, :manage_builds, @project)
.pull-right
- if @all_builds.running_or_pending.any?
= link_to 'Cancel all', cancel_all_namespace_project_builds_path(@project.namespace, @project), data: { confirm: 'Are you sure?' }, method: :post, class: 'btn btn-danger'
%ul.content-list
- if @builds.blank?
%li
.nothing-here-block No builds to show
- else
%table.table.builds
%thead
%tr
%th Status
%th Build ID
%th Commit
%th Ref
%th Runner
%th Name
%th Duration
%th Finished at
%th
- @builds.each do |build|
= render 'projects/builds/build', build: build
= paginate @builds
Loading
Loading
@@ -585,7 +585,11 @@ Gitlab::Application.routes.draw do
end
end
 
resources :builds, only: [:show] do
resources :builds, only: [:index, :show] do
collection do
post :cancel_all
end
member do
get :cancel
get :status
Loading
Loading
Loading
Loading
@@ -9,6 +9,55 @@ describe "Builds" do
@gl_project.team << [@user, :master]
end
 
describe "GET /:project/builds" do
context "All builds" do
before do
@build.success
visit namespace_project_builds_path(@gl_project.namespace, @gl_project)
end
it { expect(page).to have_content 'All builds' }
it { expect(page).to have_content @build.short_sha }
it { expect(page).to have_content @build.ref }
it { expect(page).to have_content @build.name }
it { expect(page).to_not have_content 'Cancel all' }
end
context "Pending scope" do
before do
@build.success
visit namespace_project_builds_path(@gl_project.namespace, @gl_project, scope: :pending)
end
it { expect(page).to have_content 'No builds to show' }
it { expect(page).to_not have_content 'Cancel all' }
end
context "Running scope" do
before do
@build.run!
visit namespace_project_builds_path(@gl_project.namespace, @gl_project, scope: :running)
end
it { expect(page).to have_content 'Running' }
it { expect(page).to have_content 'Cancel all' }
it { expect(page).to have_content @build.short_sha }
it { expect(page).to have_content @build.ref }
it { expect(page).to have_content @build.name }
end
end
describe "POST /:project/builds/:id/cancel_all" do
before do
@build.run!
visit cancel_namespace_project_build_path(@gl_project.namespace, @gl_project, @build)
end
it { expect(page).to have_content 'All builds' }
it { expect(page).to have_content 'canceled' }
it { expect(page).to_not have_content 'Cancel all' }
end
describe "GET /:project/builds/:id" do
before do
visit namespace_project_build_path(@gl_project.namespace, @gl_project, @build)
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment