Migrate CI::Project to Project

This commit is contained in:
Kamil Trzcinski 2015-12-04 12:55:23 +01:00
parent 8b4cdc50fc
commit e80e3f5372
161 changed files with 972 additions and 2660 deletions

View file

@ -0,0 +1,23 @@
class Admin::BuildsController < Admin::ApplicationController
def index
@scope = params[:scope]
@all_builds = Ci::Build
@builds = @all_builds.order('created_at DESC')
@builds =
case @scope
when 'all'
@builds
when 'finished'
@builds.finished
else
@builds.running_or_pending.reverse_order
end
@builds = @builds.page(params[:page]).per(30)
end
def cancel_all
Ci::Build.running_or_pending.each(&:cancel)
redirect_to admin_builds_path
end
end

View file

@ -0,0 +1,35 @@
class Admin::RunnerProjectsController < Admin::ApplicationController
before_action :project, only: [:create]
def index
@runner_projects = project.ci_runner_projects.all
@runner_project = project.ci_runner_projects.new
end
def create
@runner = Ci::Runner.find(params[:runner_project][:runner_id])
if @runner.assign_to(@project, current_user)
redirect_to admin_runner_path(@runner)
else
redirect_to admin_runner_path(@runner), alert: 'Failed adding runner to project'
end
end
def destroy
rp = Ci::RunnerProject.find(params[:id])
runner = rp.runner
rp.destroy
redirect_to admin_runner_path(runner)
end
private
def project
@project = Project.find_with_namespace(
[params[:namespace_id], '/', params[:project_id]].join('')
)
@project || render_404
end
end

View file

@ -0,0 +1,63 @@
class Admin::RunnersController < Admin::ApplicationController
before_action :runner, except: :index
def index
@runners = Ci::Runner.order('id DESC')
@runners = @runners.search(params[:search]) if params[:search].present?
@runners = @runners.page(params[:page]).per(30)
@active_runners_cnt = Ci::Runner.online.count
end
def show
@builds = @runner.builds.order('id DESC').first(30)
@projects =
if params[:search].present?
::Project.search(params[:search])
else
Project.all
end
@projects = @projects.where.not(id: @runner.projects.select(:id)) if @runner.projects.any?
@projects = @projects.page(params[:page]).per(30)
end
def update
@runner.update_attributes(runner_params)
respond_to do |format|
format.js
format.html { redirect_to admin_runner_path(@runner) }
end
end
def destroy
@runner.destroy
redirect_to admin_runners_path
end
def resume
if @runner.update_attributes(active: true)
redirect_to admin_runners_path, notice: 'Runner was successfully updated.'
else
redirect_to admin_runners_path, alert: 'Runner was not updated.'
end
end
def pause
if @runner.update_attributes(active: false)
redirect_to admin_runners_path, notice: 'Runner was successfully updated.'
else
redirect_to admin_runners_path, alert: 'Runner was not updated.'
end
end
private
def runner
@runner ||= Ci::Runner.find(params[:id])
end
def runner_params
params.require(:runner).permit(:token, :description, :tag_list, :active)
end
end

View file

@ -1,10 +0,0 @@
module Ci
module Admin
class ApplicationController < Ci::ApplicationController
before_action :authenticate_user!
before_action :authenticate_admin!
layout "ci/admin"
end
end
end

View file

@ -1,31 +0,0 @@
module Ci
class Admin::ApplicationSettingsController < Ci::Admin::ApplicationController
before_action :set_application_setting
def show
end
def update
if @application_setting.update_attributes(application_setting_params)
redirect_to ci_admin_application_settings_path,
notice: 'Application settings saved successfully'
else
render :show
end
end
private
def set_application_setting
@application_setting = Ci::ApplicationSetting.current
@application_setting ||= Ci::ApplicationSetting.create_from_defaults
end
def application_setting_params
params.require(:application_setting).permit(
:all_broken_builds,
:add_pusher,
)
end
end
end

View file

@ -1,18 +0,0 @@
module Ci
class Admin::BuildsController < Ci::Admin::ApplicationController
def index
@scope = params[:scope]
@builds = Ci::Build.order('created_at DESC').page(params[:page]).per(30)
@builds =
case @scope
when "pending"
@builds.pending
when "running"
@builds.running
else
@builds
end
end
end
end

View file

@ -1,9 +0,0 @@
module Ci
class Admin::EventsController < Ci::Admin::ApplicationController
EVENTS_PER_PAGE = 50
def index
@events = Ci::Event.admin.order('created_at DESC').page(params[:page]).per(EVENTS_PER_PAGE)
end
end
end

View file

@ -1,19 +0,0 @@
module Ci
class Admin::ProjectsController < Ci::Admin::ApplicationController
def index
@projects = Ci::Project.ordered_by_last_commit_date.page(params[:page]).per(30)
end
def destroy
project.destroy
redirect_to ci_projects_url
end
protected
def project
@project ||= Ci::Project.find(params[:id])
end
end
end

View file

@ -1,34 +0,0 @@
module Ci
class Admin::RunnerProjectsController < Ci::Admin::ApplicationController
layout 'ci/project'
def index
@runner_projects = project.runner_projects.all
@runner_project = project.runner_projects.new
end
def create
@runner = Ci::Runner.find(params[:runner_project][:runner_id])
if @runner.assign_to(project, current_user)
redirect_to ci_admin_runner_path(@runner)
else
redirect_to ci_admin_runner_path(@runner), alert: 'Failed adding runner to project'
end
end
def destroy
rp = Ci::RunnerProject.find(params[:id])
runner = rp.runner
rp.destroy
redirect_to ci_admin_runner_path(runner)
end
private
def project
@project ||= Ci::Project.find(params[:project_id])
end
end
end

View file

@ -1,73 +0,0 @@
module Ci
class Admin::RunnersController < Ci::Admin::ApplicationController
before_action :runner, except: :index
def index
@runners = Ci::Runner.order('id DESC')
@runners = @runners.search(params[:search]) if params[:search].present?
@runners = @runners.page(params[:page]).per(30)
@active_runners_cnt = Ci::Runner.online.count
end
def show
@builds = @runner.builds.order('id DESC').first(30)
@projects = Ci::Project.all
if params[:search].present?
@gl_projects = ::Project.search(params[:search])
@projects = @projects.where(gitlab_id: @gl_projects.select(:id))
end
@projects = @projects.where("ci_projects.id NOT IN (?)", @runner.projects.pluck(:id)) if @runner.projects.any?
@projects = @projects.joins(:gl_project)
@projects = @projects.page(params[:page]).per(30)
end
def update
@runner.update_attributes(runner_params)
respond_to do |format|
format.js
format.html { redirect_to ci_admin_runner_path(@runner) }
end
end
def destroy
@runner.destroy
redirect_to ci_admin_runners_path
end
def resume
if @runner.update_attributes(active: true)
redirect_to ci_admin_runners_path, notice: 'Runner was successfully updated.'
else
redirect_to ci_admin_runners_path, alert: 'Runner was not updated.'
end
end
def pause
if @runner.update_attributes(active: false)
redirect_to ci_admin_runners_path, notice: 'Runner was successfully updated.'
else
redirect_to ci_admin_runners_path, alert: 'Runner was not updated.'
end
end
def assign_all
Ci::Project.unassigned(@runner).all.each do |project|
@runner.assign_to(project, current_user)
end
redirect_to ci_admin_runner_path(@runner), notice: "Runner was assigned to all projects"
end
private
def runner
@runner ||= Ci::Runner.find(params[:id])
end
def runner_params
params.require(:runner).permit(:token, :description, :tag_list, :active)
end
end
end

View file

@ -4,8 +4,6 @@ module Ci
"app/helpers/ci"
end
helper_method :gl_project
private
def authenticate_token!
@ -15,13 +13,13 @@ module Ci
end
def authorize_access_project!
unless can?(current_user, :read_project, gl_project)
unless can?(current_user, :read_project, project)
return page_404
end
end
def authorize_manage_builds!
unless can?(current_user, :manage_builds, gl_project)
unless can?(current_user, :manage_builds, project)
return page_404
end
end
@ -31,7 +29,7 @@ module Ci
end
def authorize_manage_project!
unless can?(current_user, :admin_project, gl_project)
unless can?(current_user, :admin_project, project)
return page_404
end
end
@ -58,9 +56,5 @@ module Ci
count: count
}
end
def gl_project
::Project.find(@project.gitlab_id)
end
end
end

View file

@ -1,5 +1,5 @@
module Ci
class LintsController < Ci::ApplicationController
class LintsController < ApplicationController
before_action :authenticate_user!
def show

View file

@ -3,13 +3,12 @@ module Ci
before_action :project, except: [:index]
before_action :authenticate_user!, except: [:index, :build, :badge]
before_action :authorize_access_project!, except: [:index, :badge]
before_action :authorize_manage_project!, only: [:toggle_shared_runners, :dumped_yaml]
before_action :no_cache, only: [:badge]
protect_from_forgery
def show
# Temporary compatibility with CI badges pointing to CI project page
redirect_to namespace_project_path(project.gl_project.namespace, project.gl_project)
redirect_to namespace_project_path(project.namespace, project)
end
# Project status badge
@ -20,16 +19,11 @@ module Ci
send_file image.path, filename: image.name, disposition: 'inline', type:"image/svg+xml"
end
def toggle_shared_runners
project.toggle!(:shared_runners_enabled)
redirect_to namespace_project_runners_path(project.gl_project.namespace, project.gl_project)
end
protected
def project
@project ||= Ci::Project.find(params[:id])
# TODO: what to do here?
@project ||= Project.find_by_ci_id(params[:id])
end
def no_cache

View file

@ -1,34 +0,0 @@
module Ci
class RunnerProjectsController < Ci::ApplicationController
before_action :authenticate_user!
before_action :project
before_action :authorize_manage_project!
def create
@runner = Ci::Runner.find(params[:runner_project][:runner_id])
return head(403) unless current_user.ci_authorized_runners.include?(@runner)
path = runners_path(@project.gl_project)
if @runner.assign_to(project, current_user)
redirect_to path
else
redirect_to path, alert: 'Failed adding runner to project'
end
end
def destroy
runner_project = project.runner_projects.find(params[:id])
runner_project.destroy
redirect_to runners_path(@project.gl_project)
end
private
def project
@project ||= Ci::Project.find(params[:project_id])
end
end
end

View file

@ -31,8 +31,4 @@ class Projects::ApplicationController < ApplicationController
def builds_enabled
return render_404 unless @project.builds_enabled?
end
def ci_project
@ci_project ||= @project.ensure_gitlab_ci_project
end
end

View file

@ -1,5 +1,4 @@
class Projects::BuildsController < Projects::ApplicationController
before_action :ci_project
before_action :build, except: [:index, :cancel_all]
before_action :authorize_manage_builds!, except: [:index, :show, :status]
@ -30,7 +29,7 @@ class Projects::BuildsController < Projects::ApplicationController
end
def show
@builds = @ci_project.commits.find_by_sha(@build.sha).builds.order('id DESC')
@builds = @project.ci_commits.find_by_sha(@build.sha).builds.order('id DESC')
@builds = @builds.where("id not in (?)", @build.id)
@commit = @build.commit
@ -77,7 +76,7 @@ class Projects::BuildsController < Projects::ApplicationController
private
def build
@build ||= ci_project.builds.unscoped.find_by!(id: params[:id])
@build ||= project.ci_builds.unscoped.find_by!(id: params[:id])
end
def artifacts_file
@ -85,7 +84,7 @@ class Projects::BuildsController < Projects::ApplicationController
end
def build_path(build)
namespace_project_build_path(build.gl_project.namespace, build.gl_project, build)
namespace_project_build_path(build.project.namespace, build.project, build)
end
def authorize_manage_builds!

View file

@ -1,36 +0,0 @@
class Projects::CiSettingsController < Projects::ApplicationController
before_action :ci_project
before_action :authorize_admin_project!
layout "project_settings"
def edit
end
def update
if ci_project.update_attributes(project_params)
Ci::EventService.new.change_project_settings(current_user, ci_project)
redirect_to edit_namespace_project_ci_settings_path(project.namespace, project), notice: 'Project was successfully updated.'
else
render action: "edit"
end
end
def destroy
ci_project.destroy
Ci::EventService.new.remove_project(current_user, ci_project)
project.gitlab_ci_service.update_attributes(active: false)
redirect_to project_path(project), notice: "CI was disabled for this project"
end
protected
def project_params
params.require(:project).permit(:path, :timeout, :timeout_in_minutes, :default_ref, :always_build,
:polling_interval, :public, :ssh_url_to_repo, :allow_git_fetch, :email_recipients,
:email_add_pusher, :email_only_broken_builds, :coverage_regex, :shared_runners_enabled, :token,
{ variables_attributes: [:id, :key, :value, :_destroy] })
end
end

View file

@ -31,7 +31,6 @@ class Projects::CommitController < Projects::ApplicationController
end
def builds
@ci_project = @project.gitlab_ci_project
end
def cancel_builds

View file

@ -25,13 +25,11 @@ class Projects::GraphsController < Projects::ApplicationController
end
def ci
ci_project = @project.gitlab_ci_project
@charts = {}
@charts[:week] = Ci::Charts::WeekChart.new(ci_project)
@charts[:month] = Ci::Charts::MonthChart.new(ci_project)
@charts[:year] = Ci::Charts::YearChart.new(ci_project)
@charts[:build_times] = Ci::Charts::BuildTime.new(ci_project)
@charts[:week] = Ci::Charts::WeekChart.new(project)
@charts[:month] = Ci::Charts::MonthChart.new(project)
@charts[:year] = Ci::Charts::YearChart.new(project)
@charts[:build_times] = Ci::Charts::BuildTime.new(project)
end
def languages

View file

@ -0,0 +1,26 @@
class Projects::RunnerProjectsController < Projects::ApplicationController
before_action :authorize_admin_project!
layout 'project_settings'
def create
@runner = Ci::Runner.find(params[:runner_project][:runner_id])
return head(403) unless current_user.ci_authorized_runners.include?(@runner)
path = runners_path(project)
if @runner.assign_to(project, current_user)
redirect_to path
else
redirect_to path, alert: 'Failed adding runner to project'
end
end
def destroy
runner_project = project.ci_runner_projects.find(params[:id])
runner_project.destroy
redirect_to runners_path(project)
end
end

View file

@ -1,14 +1,13 @@
class Projects::RunnersController < Projects::ApplicationController
before_action :ci_project
before_action :set_runner, only: [:edit, :update, :destroy, :pause, :resume, :show]
before_action :authorize_admin_project!
layout 'project_settings'
def index
@runners = @ci_project.runners.ordered
@runners = project.ci_runners.ordered
@specific_runners = current_user.ci_authorized_runners.
where.not(id: @ci_project.runners).
where.not(id: project.ci_runners).
ordered.page(params[:page]).per(20)
@shared_runners = Ci::Runner.shared.active
@shared_runners_count = @shared_runners.count(:all)
@ -26,7 +25,7 @@ class Projects::RunnersController < Projects::ApplicationController
end
def destroy
if @runner.only_for?(@ci_project)
if @runner.only_for?(project)
@runner.destroy
end
@ -52,10 +51,16 @@ class Projects::RunnersController < Projects::ApplicationController
def show
end
def toggle_shared_runners
project.toggle!(:shared_runners_enabled)
redirect_to namespace_project_runners_path(project.namespace, project)
end
protected
def set_runner
@runner ||= @ci_project.runners.find(params[:id])
@runner ||= project.ci_runners.find(params[:id])
end
def runner_params

View file

@ -1,22 +1,21 @@
class Projects::TriggersController < Projects::ApplicationController
before_action :ci_project
before_action :authorize_admin_project!
layout 'project_settings'
def index
@triggers = @ci_project.triggers
@triggers = project.ci_triggers
@trigger = Ci::Trigger.new
end
def create
@trigger = @ci_project.triggers.new
@trigger = project.ci_triggers.new
@trigger.save
if @trigger.valid?
redirect_to namespace_project_triggers_path(@project.namespace, @project)
else
@triggers = @ci_project.triggers.select(&:persisted?)
@triggers = project.ci_triggers.select(&:persisted?)
render :index
end
end
@ -30,6 +29,6 @@ class Projects::TriggersController < Projects::ApplicationController
private
def trigger
@trigger ||= @ci_project.triggers.find(params[:id])
@trigger ||= project.ci_triggers.find(params[:id])
end
end

View file

@ -1,5 +1,4 @@
class Projects::VariablesController < Projects::ApplicationController
before_action :ci_project
before_action :authorize_admin_project!
layout 'project_settings'
@ -8,9 +7,7 @@ class Projects::VariablesController < Projects::ApplicationController
end
def update
if ci_project.update_attributes(project_params)
Ci::EventService.new.change_project_settings(current_user, ci_project)
if project.update_attributes(project_params)
redirect_to namespace_project_variables_path(project.namespace, project), notice: 'Variables were successfully updated.'
else
render action: 'show'
@ -20,6 +17,6 @@ class Projects::VariablesController < Projects::ApplicationController
private
def project_params
params.require(:project).permit({ variables_attributes: [:id, :key, :value, :_destroy] })
params.require(:project).permit({ ci_variables_attributes: [:id, :key, :value, :_destroy] })
end
end

View file

@ -210,10 +210,10 @@ class ProjectsController < ApplicationController
def project_params
params.require(:project).permit(
:name, :path, :description, :issues_tracker, :tag_list,
:name, :path, :description, :issues_tracker, :tag_list, :token,
:issues_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id, :default_branch,
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar,
:builds_enabled
:builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex,
)
end

View file

@ -1,17 +0,0 @@
module Ci
module GitlabHelper
def no_turbolink
{ :"data-no-turbolink" => "data-no-turbolink" }
end
def yaml_web_editor_link(project)
commits = project.commits
if commits.any? && commits.last.ci_yaml_file
"#{project.gitlab_url}/edit/master/.gitlab-ci.yml"
else
"#{project.gitlab_url}/new/master"
end
end
end
end

View file

@ -1,36 +0,0 @@
module Ci
module ProjectsHelper
def ref_tab_class ref = nil
'active' if ref == @ref
end
def success_ratio(success_builds, failed_builds)
failed_builds = failed_builds.count(:all)
success_builds = success_builds.count(:all)
return 100 if failed_builds.zero?
ratio = (success_builds.to_f / (success_builds + failed_builds)) * 100
ratio.to_i
end
def markdown_badge_code(project, ref)
url = status_ci_project_url(project, ref: ref, format: 'png')
"[![build status](#{url})](#{ci_project_url(project, ref: ref)})"
end
def html_badge_code(project, ref)
url = status_ci_project_url(project, ref: ref, format: 'png')
"<a href='#{ci_project_url(project, ref: ref)}'><img src='#{url}' /></a>"
end
def project_uses_specific_runner?(project)
project.runners.any?
end
def no_runners_for_project?(project)
project.runners.blank? &&
Ci::Runner.shared.blank?
end
end
end

View file

@ -0,0 +1,11 @@
module CiBadgeHelper
def markdown_badge_code(project, ref)
url = status_ci_project_url(project, ref: ref, format: 'png')
"[![build status](#{url})](#{ci_project_url(project, ref: ref)})"
end
def html_badge_code(project, ref)
url = status_ci_project_url(project, ref: ref, format: 'png')
"<a href='#{ci_project_url(project, ref: ref)}'><img src='#{url}' /></a>"
end
end

View file

@ -1,6 +1,6 @@
module CiStatusHelper
def ci_status_path(ci_commit)
project = ci_commit.gl_project
project = ci_commit.project
builds_namespace_project_commit_path(project.namespace, project, ci_commit.sha)
end
@ -63,4 +63,9 @@ module CiStatusHelper
ci_status_icon(ci_commit)
end
end
def no_runners_for_project?(project)
project.ci_runners.blank? &&
Ci::Runner.shared.blank?
end
end

View file

@ -16,4 +16,14 @@ module GraphHelper
ids = parents.map { |p| p.id }
ids.zip(parent_spaces)
end
def success_ratio(success_builds, failed_builds)
failed_builds = failed_builds.count(:all)
success_builds = success_builds.count(:all)
return 100 if failed_builds.zero?
ratio = (success_builds.to_f / (success_builds + failed_builds)) * 100
ratio.to_i
end
end

View file

@ -19,7 +19,7 @@ module RunnersHelper
id = "\##{runner.id}"
if current_user && current_user.admin
link_to ci_admin_runner_path(runner) do
link_to admin_runner_path(runner) do
display_name + id
end
else

View file

@ -0,0 +1,11 @@
module YamlHelper
def yaml_web_editor_link(project)
commits = project.ci_commits
if commits.any? && commits.last.ci_yaml_file
"#{project.gitlab_url}/edit/master/.gitlab-ci.yml"
else
"#{project.gitlab_url}/new/master"
end
end
end

View file

@ -1,38 +0,0 @@
# == Schema Information
#
# Table name: ci_application_settings
#
# id :integer not null, primary key
# all_broken_builds :boolean
# add_pusher :boolean
# created_at :datetime
# updated_at :datetime
#
module Ci
class ApplicationSetting < ActiveRecord::Base
extend Ci::Model
CACHE_KEY = 'ci_application_setting.last'
after_commit do
Rails.cache.write(CACHE_KEY, self)
end
def self.expire
Rails.cache.delete(CACHE_KEY)
end
def self.current
Rails.cache.fetch(CACHE_KEY) do
Ci::ApplicationSetting.last
end
end
def self.create_from_defaults
create(
all_broken_builds: Settings.gitlab_ci['all_broken_builds'],
add_pusher: Settings.gitlab_ci['add_pusher'],
)
end
end
end

View file

@ -84,6 +84,7 @@ module Ci
new_build.options = build.options
new_build.commands = build.commands
new_build.tag_list = build.tag_list
new_build.gl_project_id = build.gl_project_id
new_build.commit_id = build.commit_id
new_build.name = build.name
new_build.allow_failure = build.allow_failure
@ -101,14 +102,9 @@ module Ci
end
after_transition any => [:success, :failed, :canceled] do |build, transition|
return unless build.gl_project
project = build.project
if project.coverage_enabled?
build.update_coverage
end
return unless build.project
build.update_coverage
build.commit.create_next_builds(build)
build.execute_hooks
end
@ -119,7 +115,7 @@ module Ci
end
def retryable?
commands.present?
project.builds_enabled? && commands.present?
end
def retried?
@ -132,7 +128,7 @@ module Ci
end
def timeout
project.timeout
project.build_timeout
end
def variables
@ -151,26 +147,21 @@ module Ci
project.name
end
def project_recipients
recipients = project.email_recipients.split(' ')
if project.email_add_pusher? && user.present? && user.notification_email.present?
recipients << user.notification_email
end
recipients.uniq
end
def repo_url
project.repo_url_with_auth
auth = "gitlab-ci-token:#{token}@"
project.http_url_to_repo.sub(/^https?:\/\//) do |prefix|
prefix + auth
end
end
def allow_git_fetch
project.allow_git_fetch
project.build_allow_git_fetch
end
def update_coverage
coverage = extract_coverage(trace, project.coverage_regex)
coverage_regex = project.build_coverage_regex
return unless coverage_regex
coverage = extract_coverage(trace, coverage_regex)
if coverage.is_a? Numeric
update_attributes(coverage: coverage)
@ -239,20 +230,20 @@ module Ci
def target_url
Gitlab::Application.routes.url_helpers.
namespace_project_build_url(gl_project.namespace, gl_project, self)
namespace_project_build_url(project.namespace, project, self)
end
def cancel_url
if active?
Gitlab::Application.routes.url_helpers.
cancel_namespace_project_build_path(gl_project.namespace, gl_project, self)
cancel_namespace_project_build_path(project.namespace, project, self)
end
end
def retry_url
if retryable?
Gitlab::Application.routes.url_helpers.
retry_namespace_project_build_path(gl_project.namespace, gl_project, self)
retry_namespace_project_build_path(project.namespace, project, self)
end
end
@ -271,16 +262,18 @@ module Ci
def download_url
if artifacts_file.exists?
Gitlab::Application.routes.url_helpers.
download_namespace_project_build_path(gl_project.namespace, gl_project, self)
download_namespace_project_build_path(project.namespace, project, self)
end
end
def execute_hooks
build_data = Gitlab::BuildDataBuilder.build(self)
gl_project.execute_hooks(build_data.dup, :build_hooks)
gl_project.execute_services(build_data.dup, :build_hooks)
project.execute_hooks(build_data.dup, :build_hooks)
project.execute_services(build_data.dup, :build_hooks)
end
private
def yaml_variables
@ -294,7 +287,7 @@ module Ci
end
def project_variables
project.variables.map do |variable|
project.ci_variables.map do |variable|
{ key: variable.key, value: variable.value, public: false }
end
end

View file

@ -20,8 +20,8 @@ module Ci
class Commit < ActiveRecord::Base
extend Ci::Model
belongs_to :gl_project, class_name: '::Project', foreign_key: :gl_project_id
has_many :statuses, dependent: :destroy, class_name: 'CommitStatus'
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
has_many :statuses, class_name: 'CommitStatus'
has_many :builds, class_name: 'Ci::Build'
has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest'
@ -38,10 +38,6 @@ module Ci
sha
end
def project
@project ||= gl_project.ensure_gitlab_ci_project
end
def project_id
project.id
end
@ -79,7 +75,7 @@ module Ci
end
def commit_data
@commit ||= gl_project.commit(sha)
@commit ||= project.commit(sha)
rescue
nil
end
@ -187,11 +183,9 @@ module Ci
end
def coverage
if project.coverage_enabled?
coverage_array = latest_builds.map(&:coverage).compact
if coverage_array.size >= 1
'%.2f' % (coverage_array.reduce(:+) / coverage_array.size)
end
coverage_array = latest_builds.map(&:coverage).compact
if coverage_array.size >= 1
'%.2f' % (coverage_array.reduce(:+) / coverage_array.size)
end
end
@ -201,7 +195,7 @@ module Ci
def config_processor
return nil unless ci_yaml_file
@config_processor ||= Ci::GitlabCiYamlProcessor.new(ci_yaml_file, gl_project.path_with_namespace)
@config_processor ||= Ci::GitlabCiYamlProcessor.new(ci_yaml_file, project.path_with_namespace)
rescue Ci::GitlabCiYamlProcessor::ValidationError, Psych::SyntaxError => e
save_yaml_error(e.message)
nil
@ -211,7 +205,7 @@ module Ci
end
def ci_yaml_file
@ci_yaml_file ||= gl_project.repository.blob_at(sha, '.gitlab-ci.yml').data
@ci_yaml_file ||= project.repository.blob_at(sha, '.gitlab-ci.yml').data
rescue
nil
end

View file

@ -1,27 +0,0 @@
# == Schema Information
#
# Table name: ci_events
#
# id :integer not null, primary key
# project_id :integer
# user_id :integer
# is_admin :integer
# description :text
# created_at :datetime
# updated_at :datetime
#
module Ci
class Event < ActiveRecord::Base
extend Ci::Model
belongs_to :project, class_name: 'Ci::Project'
validates :description,
presence: true,
length: { in: 5..200 }
scope :admin, ->(){ where(is_admin: true) }
scope :project_wide, ->(){ where(is_admin: false) }
end
end

View file

@ -1,151 +0,0 @@
# == Schema Information
#
# Table name: ci_projects
#
# id :integer not null, primary key
# name :string(255)
# timeout :integer default(3600), not null
# created_at :datetime
# updated_at :datetime
# token :string(255)
# default_ref :string(255)
# path :string(255)
# always_build :boolean default(FALSE), not null
# polling_interval :integer
# public :boolean default(FALSE), not null
# ssh_url_to_repo :string(255)
# gitlab_id :integer
# allow_git_fetch :boolean default(TRUE), not null
# email_recipients :string(255) default(""), not null
# email_add_pusher :boolean default(TRUE), not null
# email_only_broken_builds :boolean default(TRUE), not null
# skip_refs :string(255)
# coverage_regex :string(255)
# shared_runners_enabled :boolean default(FALSE)
# generated_yaml_config :text
#
module Ci
class Project < ActiveRecord::Base
extend Ci::Model
include Ci::ProjectStatus
belongs_to :gl_project, class_name: '::Project', foreign_key: :gitlab_id
has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject'
has_many :runners, through: :runner_projects, class_name: 'Ci::Runner'
has_many :events, dependent: :destroy, class_name: 'Ci::Event'
has_many :variables, dependent: :destroy, class_name: 'Ci::Variable'
has_many :triggers, dependent: :destroy, class_name: 'Ci::Trigger'
accepts_nested_attributes_for :variables, allow_destroy: true
delegate :name_with_namespace, :path_with_namespace, :web_url, :http_url_to_repo, :ssh_url_to_repo, to: :gl_project
#
# Validations
#
validates_presence_of :timeout, :token, :default_ref, :gitlab_id
validates_uniqueness_of :gitlab_id
validates :polling_interval,
presence: true,
if: ->(project) { project.always_build.present? }
before_validation :set_default_values
class << self
include Ci::CurrentSettings
def unassigned(runner)
joins("LEFT JOIN #{Ci::RunnerProject.table_name} ON #{Ci::RunnerProject.table_name}.project_id = #{Ci::Project.table_name}.id " \
"AND #{Ci::RunnerProject.table_name}.runner_id = #{runner.id}").
where("#{Ci::RunnerProject.table_name}.project_id" => nil)
end
def ordered_by_last_commit_date
last_commit_subquery = "(SELECT gl_project_id, MAX(committed_at) committed_at FROM #{Ci::Commit.table_name} GROUP BY gl_project_id)"
joins("LEFT JOIN #{last_commit_subquery} AS last_commit ON #{Ci::Project.table_name}.gitlab_id = last_commit.gl_project_id").
joins(:gl_project).
order("CASE WHEN last_commit.committed_at IS NULL THEN 1 ELSE 0 END, last_commit.committed_at DESC")
end
end
def name
name_with_namespace
end
def path
path_with_namespace
end
def gitlab_url
web_url
end
def any_runners?(&block)
if runners.active.any?(&block)
return true
end
shared_runners_enabled && Ci::Runner.shared.active.any?(&block)
end
def set_default_values
self.token = SecureRandom.hex(15) if self.token.blank?
self.default_ref ||= 'master'
end
def tracked_refs
@tracked_refs ||= default_ref.split(",").map { |ref| ref.strip }
end
def valid_token? token
self.token && self.token == token
end
def no_running_builds?
# Get running builds not later than 3 days ago to ignore hangs
builds.running.where("updated_at > ?", 3.days.ago).empty?
end
def email_notification?
email_add_pusher || email_recipients.present?
end
def timeout_in_minutes
timeout / 60
end
def timeout_in_minutes=(value)
self.timeout = value.to_i * 60
end
def coverage_enabled?
coverage_regex.present?
end
# Build a clone-able repo url
# using http and basic auth
def repo_url_with_auth
auth = "gitlab-ci-token:#{token}@"
http_url_to_repo.sub(/^https?:\/\//) do |prefix|
prefix + auth
end
end
def setup_finished?
commits.any?
end
def commits
gl_project.ci_commits.ordered
end
def builds
gl_project.ci_builds
end
end
end

View file

@ -1,31 +0,0 @@
module Ci
module ProjectStatus
def status
last_commit.status if last_commit
end
def broken?
last_commit.failed? if last_commit
end
def success?
last_commit.success? if last_commit
end
def broken_or_success?
broken? || success?
end
def last_commit
@last_commit ||= commits.last if commits.any?
end
def last_commit_date
last_commit.try(:created_at)
end
def human_status
status
end
end
end

View file

@ -25,7 +25,7 @@ module Ci
has_many :builds, class_name: 'Ci::Build'
has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject'
has_many :projects, through: :runner_projects, class_name: 'Ci::Project'
has_many :projects, through: :runner_projects, class_name: '::Project', foreign_key: :gl_project_id
has_one :last_build, ->() { order('id DESC') }, class_name: 'Ci::Build'
@ -45,10 +45,6 @@ module Ci
query: "%#{query.try(:downcase)}%")
end
def gl_projects_ids
projects.select(:gitlab_id)
end
def set_default_values
self.token = SecureRandom.hex(15) if self.token.blank?
end
@ -56,7 +52,7 @@ module Ci
def assign_to(project, current_user = nil)
self.is_shared = false if shared?
self.save
project.runner_projects.create!(runner_id: self.id)
project.ci_runner_projects.create!(runner_id: self.id)
end
def display_name

View file

@ -14,8 +14,8 @@ module Ci
extend Ci::Model
belongs_to :runner, class_name: 'Ci::Runner'
belongs_to :project, class_name: 'Ci::Project'
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
validates_uniqueness_of :runner_id, scope: :project_id
validates_uniqueness_of :runner_id, scope: :gl_project_id
end
end

View file

@ -16,7 +16,7 @@ module Ci
acts_as_paranoid
belongs_to :project, class_name: 'Ci::Project'
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest'
validates_presence_of :token

View file

@ -15,10 +15,10 @@ module Ci
class Variable < ActiveRecord::Base
extend Ci::Model
belongs_to :project, class_name: 'Ci::Project'
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
validates_presence_of :key
validates_uniqueness_of :key, scope: :project_id
validates_uniqueness_of :key, scope: :gl_project_id
attr_encrypted :value, mode: :per_attribute_iv_and_salt, key: Gitlab::Application.secrets.db_key_base
end

View file

@ -30,6 +30,7 @@
class CommitStatus < ActiveRecord::Base
self.table_name = 'ci_builds'
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
belongs_to :commit, class_name: 'Ci::Commit'
belongs_to :user
@ -49,6 +50,7 @@ class CommitStatus < ActiveRecord::Base
scope :latest, -> { where(id: unscope(:select).select('max(id)').group(:name, :ref)) }
scope :ordered, -> { order(:ref, :stage_idx, :name) }
scope :for_ref, ->(ref) { where(ref: ref) }
scope :has_coverage?, -> { where.not(coverage: nil).any? }
state_machine :status, initial: :pending do
event :run do
@ -86,7 +88,7 @@ class CommitStatus < ActiveRecord::Base
state :canceled, value: 'canceled'
end
delegate :sha, :short_sha, :gl_project,
delegate :sha, :short_sha, :project,
to: :commit, prefix: false
# TODO: this should be removed with all references

View file

@ -56,6 +56,7 @@ class Project < ActiveRecord::Base
default_value_for :wiki_enabled, gitlab_config_features.wiki
default_value_for :wall_enabled, false
default_value_for :snippets_enabled, gitlab_config_features.snippets
default_value_for(:shared_runners_enabled) { current_application_settings.shared_runners_enabled }
# set last_activity_at to the same as created_at
after_create :set_last_activity_at
@ -77,7 +78,6 @@ class Project < ActiveRecord::Base
# Project services
has_many :services
has_one :gitlab_ci_service, dependent: :destroy
has_one :campfire_service, dependent: :destroy
has_one :drone_ci_service, dependent: :destroy
has_one :emails_on_push_service, dependent: :destroy
@ -122,14 +122,21 @@ class Project < ActiveRecord::Base
has_many :deploy_keys, through: :deploy_keys_projects
has_many :users_star_projects, dependent: :destroy
has_many :starrers, through: :users_star_projects, source: :user
has_many :ci_commits, dependent: :destroy, class_name: 'Ci::Commit', foreign_key: :gl_project_id
has_many :ci_builds, through: :ci_commits, source: :builds, dependent: :destroy, class_name: 'Ci::Build'
has_many :releases, dependent: :destroy
has_many :lfs_objects_projects, dependent: :destroy
has_many :lfs_objects, through: :lfs_objects_projects
has_one :import_data, dependent: :destroy, class_name: "ProjectImportData"
has_one :gitlab_ci_project, dependent: :destroy, class_name: "Ci::Project", foreign_key: :gitlab_id
has_many :ci_commits, dependent: :destroy, class_name: 'Ci::Commit', foreign_key: :gl_project_id
has_many :ci_statuses, dependent: :destroy, class_name: 'CommitStatus', foreign_key: :gl_project_id
has_many :ci_builds, class_name: 'Ci::Build', foreign_key: :gl_project_id # the builds are created from the ci_statuses
has_many :ci_runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject', foreign_key: :gl_project_id
has_many :ci_runners, through: :ci_runner_projects, source: :runner, class_name: 'Ci::Runner'
has_many :ci_variables, dependent: :destroy, class_name: 'Ci::Variable', foreign_key: :gl_project_id
has_many :ci_triggers, dependent: :destroy, class_name: 'Ci::Trigger', foreign_key: :gl_project_id
accepts_nested_attributes_for :ci_variables, allow_destroy: true
delegate :name, to: :owner, allow_nil: true, prefix: true
delegate :members, to: :team, prefix: true
@ -162,6 +169,11 @@ class Project < ActiveRecord::Base
if: ->(project) { project.avatar.present? && project.avatar_changed? }
validates :avatar, file_size: { maximum: 200.kilobytes.to_i }
before_validation :set_random_token
def set_random_token
self.token = SecureRandom.hex(15) if self.token.blank?
end
mount_uploader :avatar, AvatarUploader
# Scopes
@ -257,6 +269,12 @@ class Project < ActiveRecord::Base
projects.iwhere('projects.path' => project_path).take
end
def find_by_ci_id(id)
ci_projects = Arel::Table.new(:ci_projects)
gitlab_id = ci_projects.where(ci_projects[:id].eq(id)).project(ci_projects[:gitlab_id])
find_by("id=(#{gitlab_id.to_sql})")
end
def visibility_levels
Gitlab::VisibilityLevel.options
end
@ -791,28 +809,6 @@ class Project < ActiveRecord::Base
ci_commit(sha) || ci_commits.create(sha: sha)
end
def ensure_gitlab_ci_project
gitlab_ci_project || create_gitlab_ci_project(
shared_runners_enabled: current_application_settings.shared_runners_enabled
)
end
# TODO: this should be migrated to Project table,
# the same as issues_enabled
def builds_enabled
gitlab_ci_service && gitlab_ci_service.active
end
def builds_enabled?
builds_enabled
end
def builds_enabled=(value)
service = gitlab_ci_service || create_gitlab_ci_service
service.active = value
service.save
end
def enable_ci
self.builds_enabled = true
end
@ -826,4 +822,28 @@ class Project < ActiveRecord::Base
forked_project_link.destroy
end
end
def any_runners?(&block)
if ci_runners.active.any?(&block)
return true
end
shared_runners_enabled? && Ci::Runner.shared.active.any?(&block)
end
def valid_token? token
self.token && self.token == token
end
def build_coverage_enabled?
build_coverage_regex.present?
end
def build_timeout_in_minutes
build_timeout / 60
end
def build_timeout_in_minutes=(value)
self.build_timeout = value.to_i * 60
end
end

View file

@ -19,76 +19,5 @@
#
class GitlabCiService < CiService
include Gitlab::Application.routes.url_helpers
after_save :compose_service_hook, if: :activated?
after_save :ensure_gitlab_ci_project, if: :activated?
def compose_service_hook
hook = service_hook || build_service_hook
hook.save
end
def ensure_gitlab_ci_project
return unless project
project.ensure_gitlab_ci_project
end
def supported_events
%w(push tag_push)
end
def execute(data)
return unless supported_events.include?(data[:object_kind])
ci_project = project.gitlab_ci_project
if ci_project
current_user = User.find_by(id: data[:user_id])
Ci::CreateCommitService.new.execute(ci_project, current_user, data)
end
end
def token
if project.gitlab_ci_project.present?
project.gitlab_ci_project.token
end
end
def get_ci_commit(sha, ref)
Ci::Project.find(project.gitlab_ci_project.id).commits.find_by_sha!(sha)
end
def commit_status(sha, ref)
get_ci_commit(sha, ref).status
rescue ActiveRecord::RecordNotFound
:error
end
def commit_coverage(sha, ref)
get_ci_commit(sha, ref).coverage
rescue ActiveRecord::RecordNotFound
:error
end
def build_page(sha, ref)
if project.gitlab_ci_project.present?
builds_namespace_project_commit_url(project.namespace, project, sha)
end
end
def title
'GitLab CI'
end
def description
'Continuous integration server from GitLab'
end
def to_param
'gitlab_ci'
end
def fields
[]
end
# this is no longer used
end

View file

@ -41,7 +41,7 @@ class Service < ActiveRecord::Base
validates :project_id, presence: true, unless: Proc.new { |service| service.template? }
scope :visible, -> { where.not(type: 'GitlabIssueTrackerService') }
scope :visible, -> { where.not(type: ['GitlabIssueTrackerService', 'GitlabCiService']) }
scope :push_hooks, -> { where(push_events: true, active: true) }
scope :tag_push_hooks, -> { where(tag_push_events: true, active: true) }
@ -188,7 +188,6 @@ class Service < ActiveRecord::Base
external_wiki
flowdock
gemnasium
gitlab_ci
hipchat
irker
jira

View file

@ -769,10 +769,9 @@ class User < ActiveRecord::Base
def ci_authorized_runners
@ci_authorized_runners ||= begin
runner_ids = Ci::RunnerProject.joins(:project).
where("ci_projects.gitlab_id IN (#{ci_projects_union.to_sql})").
runner_ids = Ci::RunnerProject.
where("ci_runner_projects.gl_project_id IN (#{ci_projects_union.to_sql})").
select(:runner_id)
Ci::Runner.specific.where(id: runner_ids)
end
end

View file

@ -29,7 +29,8 @@ module Ci
build_attrs.merge!(ref: ref,
tag: tag,
trigger_request: trigger_request,
user: user)
user: user,
gl_project_id: commit.gl_project_id)
build = commit.builds.create!(build_attrs)
build.execute_hooks

View file

@ -16,7 +16,7 @@ module Ci
end
tag = origin_ref.start_with?('refs/tags/')
commit = project.gl_project.ensure_ci_commit(sha)
commit = project.ensure_ci_commit(sha)
unless commit.skip_ci?
commit.update_committed!
commit.create_builds(ref, tag, user)

View file

@ -1,13 +1,13 @@
module Ci
class CreateTriggerRequestService
def execute(project, trigger, ref, variables = nil)
commit = project.gl_project.commit(ref)
commit = project.commit(ref)
return unless commit
# check if ref is tag
tag = project.gl_project.repository.find_tag(ref).present?
tag = project.repository.find_tag(ref).present?
ci_commit = project.gl_project.ensure_ci_commit(commit.sha)
ci_commit = project.ensure_ci_commit(commit.sha)
trigger_request = trigger.trigger_requests.create!(
variables: variables,

View file

@ -1,31 +0,0 @@
module Ci
class EventService
def remove_project(user, project)
create(
description: "Project \"#{project.name}\" has been removed by #{user.username}",
user_id: user.id,
is_admin: true
)
end
def create_project(user, project)
create(
description: "Project \"#{project.name}\" has been created by #{user.username}",
user_id: user.id,
is_admin: true
)
end
def change_project_settings(user, project)
create(
project_id: project.id,
user_id: user.id,
description: "User \"#{user.username}\" updated projects settings"
)
end
def create(*args)
Ci::Event.create!(*args)
end
end
end

View file

@ -4,10 +4,10 @@ module Ci
sha = params[:sha]
sha ||=
if params[:ref]
project.gl_project.commit(params[:ref]).try(:sha)
project.commit(params[:ref]).try(:sha)
end
commit = project.commits.ordered.find_by(sha: sha)
commit = project.ci_commits.ordered.find_by(sha: sha)
image_name = image_for_commit(commit)
image_path = Rails.root.join('public/ci', image_name)

View file

@ -8,10 +8,10 @@ module Ci
builds =
if current_runner.shared?
# don't run projects which have not enables shared runners
builds.joins(commit: { gl_project: :gitlab_ci_project }).where(ci_projects: { shared_runners_enabled: true })
builds.joins(:project).where(projects: { builds_enabled: true, shared_runners_enabled: true })
else
# do run projects which are only assigned to this runner
builds.joins(:commit).where(ci_commits: { gl_project_id: current_runner.gl_projects_ids })
builds.where(project: current_runner.projects)
end
builds = builds.order('created_at ASC')
@ -20,10 +20,9 @@ module Ci
build.can_be_served?(current_runner)
end
if build
# In case when 2 runners try to assign the same build, second runner will be declined
# with StateMachine::InvalidTransition in run! method.
# with StateMachines::InvalidTransition in run! method.
build.with_lock do
build.runner_id = current_runner.id
build.save!
@ -33,7 +32,7 @@ module Ci
build
rescue StateMachine::InvalidTransition
rescue StateMachines::InvalidTransition
nil
end
end

View file

@ -1,7 +0,0 @@
module Ci
class TestHookService
def execute(hook, current_user)
Ci::WebHookService.new.build_end(hook.project.commits.last.last_build)
end
end
end

View file

@ -7,6 +7,8 @@ module Projects
description: @project.description,
name: @project.name,
path: @project.path,
shared_runners_enabled: @project.shared_runners_enabled,
builds_enabled: @project.builds_enabled,
namespace_id: @params[:namespace].try(:id) || current_user.namespace.id
}
@ -15,19 +17,6 @@ module Projects
end
new_project = CreateService.new(current_user, new_params).execute
if new_project.persisted?
if @project.builds_enabled?
new_project.enable_ci
settings = @project.gitlab_ci_project.attributes.select do |attr_name, value|
["public", "shared_runners_enabled", "allow_git_fetch"].include? attr_name
end
new_project.gitlab_ci_project.update(settings)
end
end
new_project
end
end

View file

@ -0,0 +1,73 @@
- project = build.project
%tr.build
%td.status
= ci_status_with_icon(build.status)
%td.build-link
- if build.target_url
= link_to build.target_url do
%strong Build ##{build.id}
- else
%strong Build ##{build.id}
- if build.show_warning?
%i.fa.fa-warning.text-warning
%td
- if project
= link_to project.name_with_namespace, admin_namespace_project_path(project.namespace, project), class: "monospace"
%td
= link_to build.short_sha, namespace_project_commit_path(project.namespace, project, build.sha), class: "monospace"
%td
- if build.ref
= link_to build.ref, namespace_project_commits_path(project.namespace, project, build.ref)
- else
.light none
%td
- if build.try(:runner)
= runner_link(build.runner)
- else
.light none
%td
#{build.stage} / #{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_with_tooltip(build.finished_at)}
- if defined?(coverage) && coverage
%td.coverage
- if build.try(:coverage)
#{build.coverage}%
%td
.pull-right
- if current_user && can?(current_user, :download_build_artifacts, project) && build.download_url
= link_to build.download_url, title: 'Download artifacts' do
%i.fa.fa-download
- if current_user && can?(current_user, :manage_builds, build.project)
- if build.active?
- if build.cancel_url
= link_to build.cancel_url, method: :post, title: 'Cancel' do
%i.fa.fa-remove.cred
- elsif defined?(allow_retry) && allow_retry && build.retry_url
= link_to build.retry_url, method: :post, title: 'Retry' do
%i.fa.fa-repeat

View file

@ -0,0 +1,50 @@
.project-issuable-filter
.controls
.pull-left.hidden-xs
- if @all_builds.running_or_pending.any?
= link_to 'Cancel all', cancel_all_admin_builds_path, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', method: :post
%ul.center-top-menu
%li{class: ('active' if @scope.nil?)}
= link_to admin_builds_path do
Running
%span.badge.js-running-count= @all_builds.running_or_pending.count(:id)
%li{class: ('active' if @scope == 'finished')}
= link_to admin_builds_path(scope: :finished) do
Finished
%span.badge.js-running-count= @all_builds.finished.count(:id)
%li{class: ('active' if @scope == 'all')}
= link_to admin_builds_path(scope: :all) do
All
%span.badge.js-totalbuilds-count= @all_builds.count(:id)
.gray-content-block
#{(@scope || 'running').capitalize} builds
%ul.content-list
- if @builds.blank?
%li
.nothing-here-block No builds to show
- else
.table-holder
%table.table.builds
%thead
%tr
%th Status
%th Build ID
%th Project
%th Commit
%th Ref
%th Runner
%th Name
%th Duration
%th Finished at
%th
- @builds.each do |build|
= render "admin/builds/build", build: build
= paginate @builds, theme: 'gitlab'

View file

@ -8,14 +8,14 @@
%span.label.label-danger paused
%td
= link_to ci_admin_runner_path(runner) do
= link_to admin_runner_path(runner) do
= runner.short_sha
%td
.runner-description
= runner.description
%span (#{link_to 'edit', '#', class: 'edit-runner-link'})
.runner-description-form.hide
= form_for [:ci, :admin, runner], remote: true, html: { class: 'form-inline' } do |f|
= form_for [:admin, runner], remote: true, html: { class: 'form-inline' } do |f|
.form-group
= f.text_field :description, class: 'form-control'
= f.submit 'Save', class: 'btn'
@ -38,11 +38,11 @@
Never
%td
.pull-right
= link_to 'Edit', ci_admin_runner_path(runner), class: 'btn btn-sm'
= link_to 'Edit', admin_runner_path(runner), class: 'btn btn-sm'
&nbsp;
- if runner.active?
= link_to 'Pause', [:pause, :ci, :admin, runner], data: { confirm: "Are you sure?" }, method: :get, class: 'btn btn-danger btn-sm'
= link_to 'Pause', [:pause, :admin, runner], data: { confirm: "Are you sure?" }, method: :get, class: 'btn btn-danger btn-sm'
- else
= link_to 'Resume', [:resume, :ci, :admin, runner], method: :get, class: 'btn btn-success btn-sm'
= link_to 'Remove', [:ci, :admin, runner], data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-danger btn-sm'
= link_to 'Resume', [:resume, :admin, runner], method: :get, class: 'btn btn-success btn-sm'
= link_to 'Remove', [:admin, runner], data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-danger btn-sm'

View file

@ -25,7 +25,7 @@
.append-bottom-20.clearfix
.pull-left
= form_tag ci_admin_runners_path, id: 'runners-search', class: 'form-inline', method: :get do
= form_tag admin_runners_path, id: 'runners-search', class: 'form-inline', method: :get do
.form-group
= search_field_tag :search, params[:search], class: 'form-control', placeholder: 'Runner description or token', spellcheck: false
= submit_tag 'Search', class: 'btn'
@ -49,5 +49,5 @@
%th
- @runners.each do |runner|
= render "ci/admin/runners/runner", runner: runner
= render "admin/runners/runner", runner: runner
= paginate @runners

View file

@ -22,7 +22,7 @@
%h4 This runner will process builds only from ASSIGNED projects
%p You can't make this a shared runner.
%hr
= form_for @runner, url: ci_admin_runner_path(@runner), html: { class: 'form-horizontal' } do |f|
= form_for @runner, url: admin_runner_path(@runner), html: { class: 'form-horizontal' } do |f|
.form-group
= label_tag :token, class: 'control-label' do
Token
@ -53,29 +53,24 @@
%th
- @runner.runner_projects.each do |runner_project|
- project = runner_project.project
- if project.gl_project
- if project
%tr.alert-info
%td
%strong
= project.name
= project.name_with_namespace
%td
.pull-right
= link_to 'Disable', [:ci, :admin, project, runner_project], method: :delete, class: 'btn btn-danger btn-xs'
= link_to 'Disable', [:admin, project.namespace, project, runner_project], method: :delete, class: 'btn btn-danger btn-xs'
%table.table
%thead
%tr
%th Project
%th
.pull-right
= link_to 'Assign to all', assign_all_ci_admin_runner_path(@runner),
class: 'btn btn-sm assign-all-runner',
title: 'Assign runner to all projects',
method: :put
%tr
%td
= form_tag ci_admin_runner_path(@runner), id: 'runner-projects-search', class: 'form-inline', method: :get do
= form_tag admin_runner_path(@runner), id: 'runner-projects-search', class: 'form-inline', method: :get do
.form-group
= search_field_tag :search, params[:search], class: 'form-control', spellcheck: false
= submit_tag 'Search', class: 'btn'
@ -84,44 +79,44 @@
- @projects.each do |project|
%tr
%td
= project.name
= project.name_with_namespace
%td
.pull-right
= form_for [:ci, :admin, project, project.runner_projects.new] do |f|
= form_for [:admin, project.namespace, project, project.ci_runner_projects.new] do |f|
= f.hidden_field :runner_id, value: @runner.id
= f.submit 'Enable', class: 'btn btn-xs'
= paginate @projects
.col-md-6
%h4 Recent builds served by this runner
%table.builds.runner-builds
%table.table.builds.runner-builds
%thead
%tr
%th Build ID
%th Build
%th Status
%th Project
%th Commit
%th Finished at
- @builds.each do |build|
- gl_project = build.gl_project
- project = build.project
%tr.build
%td.id
- if gl_project
= link_to namespace_project_build_path(gl_project.namespace, gl_project, build) do
= build.id
- if project
= link_to namespace_project_build_path(project.namespace, project, build) do
%strong ##{build.id}
- else
= build.id
%strong ##{build.id}
%td.status
= ci_status_with_icon(build.status)
%td.status
- if gl_project
= gl_project.name_with_namespace
- if project
= project.name_with_namespace
%td.build-link
- if gl_project
- if project
= link_to ci_status_path(build.commit) do
%strong #{build.commit.short_sha}

View file

@ -1,24 +0,0 @@
= form_for @application_setting, url: ci_admin_application_settings_path, html: { class: 'form-horizontal fieldset-form' } do |f|
- if @application_setting.errors.any?
#error_explanation
.alert.alert-danger
- @application_setting.errors.full_messages.each do |msg|
%p= msg
%fieldset
%legend Default Project Settings
.form-group
.col-sm-offset-2.col-sm-10
.checkbox
= f.label :all_broken_builds do
= f.check_box :all_broken_builds
Send emails only on broken builds
.form-group
.col-sm-offset-2.col-sm-10
.checkbox
= f.label :add_pusher do
= f.check_box :add_pusher
Add pusher to recipients list
.form-actions
= f.submit 'Save', class: 'btn btn-primary'

View file

@ -1,3 +0,0 @@
%h3.page-title Settings
%hr
= render 'form'

View file

@ -1,34 +0,0 @@
- gl_project = build.project.gl_project
- if build.commit && build.project
%tr.build
%td.build-link
= link_to namespace_project_build_path(gl_project.namespace, gl_project, build) do
%strong #{build.id}
%td.status
= ci_status_with_icon(build.status)
%td.commit-link
= link_to ci_status_path(build.commit) do
%strong #{build.commit.short_sha}
%td.runner
- if build.runner
= link_to build.runner.id, ci_admin_runner_path(build.runner)
%td.build-project
= truncate build.project.name, length: 30
%td.build-message
%span= truncate(build.commit.git_commit_message, length: 30)
%td.build-branch
%span= truncate(build.ref, length: 25)
%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

View file

@ -1,28 +0,0 @@
%ul.nav.nav-tabs.append-bottom-20
%li{class: ("active" if @scope.nil?)}
= link_to 'All builds', ci_admin_builds_path
%li{class: ("active" if @scope == "pending")}
= link_to "Pending", ci_admin_builds_path(scope: :pending)
%li{class: ("active" if @scope == "running")}
= link_to "Running", ci_admin_builds_path(scope: :running)
%table.builds
%thead
%tr
%th Build
%th Status
%th Commit
%th Runner
%th Project
%th Message
%th Branch
%th Duration
%th Finished at
- @builds.each do |build|
= render "ci/admin/builds/build", build: build
= paginate @builds

View file

@ -1,18 +0,0 @@
.table-holder
%table.table
%thead
%tr
%th User ID
%th Description
%th When
- @events.each do |event|
%tr
%td
= event.user_id
%td
= event.description
%td.light
= time_ago_in_words event.updated_at
ago
= paginate @events

View file

@ -1,29 +0,0 @@
- last_commit = project.commits.last
%tr
%td
= project.id
%td
= link_to [:ci, project] do
%strong= project.name
%td
- if last_commit
= ci_status_with_icon(last_commit.status)
- if project.last_commit_date
&middot;
= time_ago_in_words project.last_commit_date
ago
- else
No builds yet
%td
- if project.public
%i.fa.fa-globe
Public
- else
%i.fa.fa-lock
Private
%td
= project.commits.count
%td
= link_to [:ci, :admin, project], method: :delete, class: 'btn btn-danger btn-sm' do
%i.fa.fa-remove
Remove

View file

@ -1,16 +0,0 @@
.table-holder
%table.table
%thead
%tr
%th ID
%th Name
%th Last build
%th Access
%th Builds
%th
- @projects.each do |project|
= render "ci/admin/projects/project", project: project
= paginate @projects

View file

@ -1,57 +0,0 @@
%p.lead
To register a new runner visit #{link_to 'this page ', ci_runners_path}
.row
.col-md-8
%h5 Activated:
%table.table
%tr
%th Runner ID
%th Runner Description
%th Last build
%th Builds Stats
%th Registered
%th
- @runner_projects.each do |runner_project|
- runner = runner_project.runner
- builds = runner.builds.where(project_id: @project.id)
%tr
%td
%span.badge.badge-info= runner.id
%td
= runner.display_name
%td
- last_build = builds.last
- if last_build
= link_to last_build.short_sha, [last_build.project, last_build]
- else
unknown
%td
%span.badge.badge-success
#{builds.success.count}
%span /
%span.badge.badge-important
#{builds.failed.count}
%td
#{time_ago_in_words(runner_project.created_at)} ago
%td
= link_to 'Disable', [:ci, @project, runner_project], data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-danger btn-sm right'
.col-md-4
%h5 Available
%table.table
%tr
%th ID
%th Token
%th
- (Ci::Runner.all - @project.runners).each do |runner|
%tr
%td
= runner.id
%td
= runner.token
%td
= form_for [:ci, @project, @runner_project] do |f|
= f.hidden_field :runner_id, value: runner.id
= f.submit 'Add', class: 'btn btn-sm'

View file

@ -27,7 +27,6 @@
- if commit.finished_at
%span #{time_ago_in_words commit.finished_at} ago
- if commit.project.coverage_enabled?
- if commit.coverage
%td.coverage
- if commit.coverage
#{commit.coverage}%
#{commit.coverage}%

View file

@ -4,7 +4,7 @@
%ol
%li
Add at least one runner to the project.
Go to #{link_to 'Runners page', runners_path(@project.gl_project), target: :blank} for instructions.
Go to #{link_to 'Runners page', runners_path(@project), target: :blank} for instructions.
%li
Put the .gitlab-ci.yml in the root of your repository. Examples can be found in #{link_to "Configuring project (.gitlab-ci.yml)", "http://doc.gitlab.com/ci/yaml/README.html", target: :blank}.
You can also test your .gitlab-ci.yml in the #{link_to "Lint", ci_lint_path}

View file

@ -1,7 +0,0 @@
.login-block
%h2 Login using GitLab account
%p.light
Make sure you have an account on the GitLab server
= link_to GitlabCi.config.gitlab_server.url, GitlabCi.config.gitlab_server.url, no_turbolink
%hr
= link_to "Login with GitLab", auth_ci_user_sessions_path(state: params[:state]), no_turbolink.merge( class: 'btn btn-login btn-success' )

View file

@ -1,35 +0,0 @@
%ul.nav.nav-sidebar
= nav_link do
= link_to admin_root_path, title: 'Back to admin', data: {placement: 'right'}, class: 'back-link' do
= icon('caret-square-o-left fw')
%span
Back to admin
%li.separate-item
= nav_link path: 'projects#index' do
= link_to ci_admin_projects_path do
= icon('list-alt fw')
%span
Projects
= nav_link path: 'events#index' do
= link_to ci_admin_events_path do
= icon('book fw')
%span
Events
= nav_link path: ['runners#index', 'runners#show'] do
= link_to ci_admin_runners_path do
= icon('cog fw')
%span
Runners
%span.count= Ci::Runner.count(:all)
= nav_link path: 'builds#index' do
= link_to ci_admin_builds_path do
= icon('link fw')
%span
Builds
%span.count= Ci::Build.count(:all)
= nav_link(controller: :application_settings, html_options: { class: 'separate-item'}) do
= link_to ci_admin_application_settings_path do
= icon('cogs fw')
%span
Settings

View file

@ -1,12 +0,0 @@
%ul.nav.nav-sidebar
= nav_link do
= link_to project_path(@project.gl_project), title: 'Back to project', data: {placement: 'right'}, class: 'back-link' do
= icon('caret-square-o-left fw')
%span
Back to project
%li.separate-item
= nav_link path: 'events#index' do
= link_to ci_project_events_path(@project) do
= icon('book fw')
%span
Events

View file

@ -1,11 +0,0 @@
!!! 5
%html{ lang: "en"}
= render 'layouts/head'
%body{class: "ci-body #{user_application_theme}", 'data-page' => body_data_page}
- header_title = "Admin area"
- if current_user
= render "layouts/header/default", title: header_title
- else
= render "layouts/header/public", title: header_title
= render 'layouts/ci/page', sidebar: 'nav_admin'

View file

@ -1,11 +0,0 @@
!!! 5
%html{ lang: "en"}
= render 'layouts/head'
%body{class: "ci-body #{user_application_theme}", 'data-page' => body_data_page}
- header_title = "Continuous Integration"
- if current_user
= render "layouts/header/default", title: header_title
- else
= render "layouts/header/public", title: header_title
= render 'layouts/ci/page'

View file

@ -24,11 +24,18 @@
= icon('key fw')
%span
Deploy Keys
= nav_link do
= link_to ci_admin_projects_path, title: 'Continuous Integration' do
= icon('building fw')
= nav_link path: ['runners#index', 'runners#show'] do
= link_to admin_runners_path do
= icon('cog fw')
%span
Continuous Integration
Runners
%span.count= Ci::Runner.count(:all)
= nav_link path: 'builds#index' do
= link_to admin_builds_path do
= icon('link fw')
%span
Builds
%span.count= Ci::Build.count(:all)
= nav_link(controller: :logs) do
= link_to admin_logs_path, title: 'Logs' do
= icon('file-text fw')

View file

@ -50,8 +50,3 @@
= icon('retweet fw')
%span
Triggers
= nav_link path: 'ci_settings#edit' do
= link_to edit_namespace_project_ci_settings_path(@project.namespace, @project), title: 'CI Settings' do
= icon('building fw')
%span
CI Settings

View file

@ -7,7 +7,7 @@
= @project.name
%p
Commit: #{link_to @build.short_sha, namespace_project_commit_url(@build.gl_project.namespace, @build.gl_project, @build.sha)}
Commit: #{link_to @build.short_sha, namespace_project_commit_url(@build.project.namespace, @build.project, @build.sha)}
%p
Author: #{@build.commit.git_author_name}
%p
@ -20,4 +20,4 @@
Message: #{@build.commit.git_commit_message}
%p
Build details: #{link_to "Build #{@build.id}", namespace_project_build_url(@build.gl_project.namespace, @build.gl_project, @build)}
Build details: #{link_to "Build #{@build.id}", namespace_project_build_url(@build.project.namespace, @build.project, @build)}

View file

@ -8,4 +8,4 @@ Stage: <%= @build.stage %>
Job: <%= @build.name %>
Message: <%= @build.commit.git_commit_message %>
Url: <%= namespace_project_build_url(@build.gl_project.namespace, @build.gl_project, @build) %>
Url: <%= namespace_project_build_url(@build.project.namespace, @build.project, @build) %>

View file

@ -8,7 +8,7 @@
= @project.name
%p
Commit: #{link_to @build.short_sha, namespace_project_commit_url(@build.gl_project.namespace, @build.gl_project, @build.sha)}
Commit: #{link_to @build.short_sha, namespace_project_commit_url(@build.project.namespace, @build.project, @build.sha)}
%p
Author: #{@build.commit.git_author_name}
%p
@ -21,4 +21,4 @@
Message: #{@build.commit.git_commit_message}
%p
Build details: #{link_to "Build #{@build.id}", namespace_project_build_url(@build.gl_project.namespace, @build.gl_project, @build)}
Build details: #{link_to "Build #{@build.id}", namespace_project_build_url(@build.project.namespace, @build.project, @build)}

View file

@ -8,4 +8,4 @@ Stage: <%= @build.stage %>
Job: <%= @build.name %>
Message: <%= @build.commit.git_commit_message %>
Url: <%= namespace_project_build_url(@build.gl_project.namespace, @build.gl_project, @build) %>
Url: <%= namespace_project_build_url(@build.project.namespace, @build.project, @build) %>

View file

@ -3,7 +3,7 @@
.project-issuable-filter
.controls
- if @ci_project && can?(current_user, :manage_builds, @project)
- if can?(current_user, :manage_builds, @project)
.pull-left.hidden-xs
- if @all_builds.running_or_pending.any?
= link_to 'Cancel running', cancel_all_namespace_project_builds_path(@project.namespace, @project), data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', method: :post
@ -40,7 +40,7 @@
%thead
%tr
%th Status
%th Build ID
%th Runner
%th Commit
%th Ref
%th Stage

View file

@ -56,7 +56,7 @@
%br
Go to
= link_to namespace_project_runners_path(@build.gl_project.namespace, @build.gl_project) do
= link_to namespace_project_runners_path(@build.project.namespace, @build.project) do
Runners page
.row.prepend-top-default
@ -113,7 +113,7 @@
%p
%span.attr-name Runner:
- if @build.runner && current_user && current_user.admin
= link_to "##{@build.runner.id}", ci_admin_runner_path(@build.runner.id)
= link_to "##{@build.runner.id}", admin_runner_path(@build.runner.id)
- elsif @build.runner
\##{@build.runner.id}

View file

@ -1,120 +0,0 @@
%h3.page-title
CI settings
%hr
.bs-callout.help-callout
%p
If you want to test your .gitlab-ci.yml, you can use special tool - #{link_to "Lint", ci_lint_path}
%p
Edit your
#{link_to ".gitlab-ci.yml using web-editor", yaml_web_editor_link(@ci_project)}
- unless @project.empty_repo?
%p
Paste build status image for #{@repository.root_ref} with next link
= link_to '#', class: 'badge-codes-toggle btn btn-default btn-xs' do
Status Badge
.badge-codes-block.bs-callout.bs-callout-info.hide
%p
Status badge for
%span.label.label-info #{@ref}
branch
%div
%label Markdown:
= text_field_tag 'badge_md', markdown_badge_code(@ci_project, @repository.root_ref), readonly: true, class: 'form-control'
%label Html:
= text_field_tag 'badge_html', html_badge_code(@ci_project, @repository.root_ref), readonly: true, class: 'form-control'
= nested_form_for @ci_project, url: namespace_project_ci_settings_path(@project.namespace, @project), html: { class: 'form-horizontal' } do |f|
- if @ci_project.errors.any?
#error_explanation
%p.lead= "#{pluralize(@ci_project.errors.count, "error")} prohibited this project from being saved:"
.alert.alert-error
%ul
- @ci_project.errors.full_messages.each do |msg|
%li= msg
%fieldset
%legend Build settings
.form-group
= label_tag nil, class: 'control-label' do
Get code
.col-sm-10
%p Get recent application code using the following command:
.radio
= label_tag do
= f.radio_button :allow_git_fetch, 'false'
%strong git clone
.light Slower but makes sure you have a clean dir before every build
.radio
= label_tag do
= f.radio_button :allow_git_fetch, 'true'
%strong git fetch
.light Faster
.form-group
= f.label :timeout_in_minutes, 'Timeout', class: 'control-label'
.col-sm-10
= f.number_field :timeout_in_minutes, class: 'form-control', min: '0'
.light per build in minutes
%fieldset
%legend Build Schedule
.form-group
= f.label :always_build, 'Schedule build', class: 'control-label'
.col-sm-10
.checkbox
= f.label :always_build do
= f.check_box :always_build
%span.light Repeat last build after X hours if no builds
.form-group
= f.label :polling_interval, "Build interval", class: 'control-label'
.col-sm-10
= f.number_field :polling_interval, placeholder: '5', min: '0', class: 'form-control'
.light In hours
%fieldset
%legend Project settings
.form-group
= f.label :default_ref, "Make tabs for the following branches", class: 'control-label'
.col-sm-10
= f.text_field :default_ref, class: 'form-control', placeholder: 'master, stable'
.light You will be able to filter builds by the following branches
.form-group
= f.label :public, 'Public mode', class: 'control-label'
.col-sm-10
.checkbox
= f.label :public do
= f.check_box :public
%span.light Anyone can see project and builds
.form-group
= f.label :coverage_regex, "Test coverage parsing", class: 'control-label'
.col-sm-10
.input-group
%span.input-group-addon /
= f.text_field :coverage_regex, class: 'form-control', placeholder: '\(\d+.\d+\%\) covered'
%span.input-group-addon /
.light We will use this regular expression to find test coverage output in build trace. Leave blank if you want to disable this feature
.bs-callout.bs-callout-info
%p Below are examples of regex for existing tools:
%ul
%li
Simplecov (Ruby) -
%code \(\d+.\d+\%\) covered
%li
pytest-cov (Python) -
%code \d+\%\s*$
%li
phpunit --coverage-text --colors=never (PHP) -
%code ^\s*Lines:\s*\d+.\d+\%
%fieldset
%legend Advanced settings
.form-group
= f.label :token, "CI token", class: 'control-label'
.col-sm-10
= f.text_field :token, class: 'form-control', placeholder: 'xEeFCaDAB89'
.form-actions
= f.submit 'Save changes', class: 'btn btn-save'
- unless @ci_project.new_record?
= link_to 'Remove Project', ci_project_path(@ci_project), method: :delete, data: { confirm: 'Project will be removed. Are you sure?' }, class: 'btn btn-danger pull-right'

View file

@ -1,8 +0,0 @@
.alert.alert-danger
%p
There are NO runners to build this project.
%br
You can add Specific runner for this project on Runners page
- if current_user.admin
or add Shared runner for whole application in admin area.

View file

@ -1,6 +0,0 @@
- page_title "CI Settings"
- if no_runners_for_project?(@ci_project)
= render 'no_runners'
= render 'form'

View file

@ -1,17 +1,17 @@
.gray-content-block.middle-block
.pull-right
- if @ci_project && can?(current_user, :manage_builds, @ci_commit.gl_project)
- if @ci_project && can?(current_user, :manage_builds, @ci_commit.project)
- if @ci_commit.builds.latest.failed.any?(&:retryable?)
= link_to "Retry failed", retry_builds_namespace_project_commit_path(@ci_commit.gl_project.namespace, @ci_commit.gl_project, @ci_commit.sha), class: 'btn btn-grouped btn-primary', method: :post
= link_to "Retry failed", retry_builds_namespace_project_commit_path(@ci_commit.project.namespace, @ci_commit.project, @ci_commit.sha), class: 'btn btn-grouped btn-primary', method: :post
- if @ci_commit.builds.running_or_pending.any?
= link_to "Cancel running", cancel_builds_namespace_project_commit_path(@ci_commit.gl_project.namespace, @ci_commit.gl_project, @ci_commit.sha), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post
= link_to "Cancel running", cancel_builds_namespace_project_commit_path(@ci_commit.project.namespace, @ci_commit.project, @ci_commit.sha), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post
.oneline
= pluralize @statuses.count(:id), "build"
- if defined?(link_to_commit) && link_to_commit
for commit
= link_to @ci_commit.short_sha, namespace_project_commit_path(@ci_commit.gl_project.namespace, @ci_commit.gl_project, @ci_commit.sha), class: "monospace"
= link_to @ci_commit.short_sha, namespace_project_commit_path(@ci_commit.project.namespace, @ci_commit.project, @ci_commit.sha), class: "monospace"
- if @ci_commit.duration > 0
in
= time_interval_in_words @ci_commit.duration
@ -23,7 +23,7 @@
- @ci_commit.yaml_errors.split(",").each do |error|
%li= error
- if @ci_commit.gl_project.builds_enabled? && !@ci_commit.ci_yaml_file
- if @ci_commit.project.builds_enabled? && !@ci_commit.ci_yaml_file
.bs-callout.bs-callout-warning
\.gitlab-ci.yml not found in this commit
@ -38,12 +38,12 @@
%th Name
%th Duration
%th Finished at
- if @ci_project && @ci_project.coverage_enabled?
- if @ci_commit.project.coverage_enabled?
%th Coverage
%th
- @ci_commit.refs.each do |ref|
= render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.statuses.for_ref(ref).latest.ordered,
locals: { coverage: @ci_project.try(:coverage_enabled?), stage: true, allow_retry: true }
locals: { coverage: @ci_commit.project.coverage_enabled?, stage: true, allow_retry: true }
- if @ci_commit.retried.any?
.gray-content-block.second-block
@ -60,8 +60,8 @@
%th Name
%th Duration
%th Finished at
- if @ci_project && @ci_project.coverage_enabled?
- if @ci_commit.project.coverage_enabled?
%th Coverage
%th
= render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.retried,
locals: { coverage: @ci_project.try(:coverage_enabled?), stage: true }
locals: { coverage: @ci_commit.project.coverage_enabled?, stage: true }

View file

@ -69,7 +69,7 @@
- if current_user && can?(current_user, :download_build_artifacts, @project) && commit_status.download_url
= link_to commit_status.download_url, title: 'Download artifacts' do
%i.fa.fa-download
- if current_user && can?(current_user, :manage_builds, commit_status.gl_project)
- if current_user && can?(current_user, :manage_builds, commit_status.project)
- if commit_status.active?
- if commit_status.cancel_url
= link_to commit_status.cancel_url, method: :post, title: 'Cancel' do

View file

@ -112,6 +112,62 @@
%hr
= link_to 'Remove avatar', namespace_project_avatar_path(@project.namespace, @project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar"
%fieldset.features
%legend
Continuous Integration
.form-group
.col-sm-offset-2.col-sm-10
%p Get recent application code using the following command:
.radio
= f.label :build_allow_git_fetch do
= f.radio_button :build_allow_git_fetch, 'false'
%strong git clone
%br
%span.descr Slower but makes sure you have a clean dir before every build
.radio
= f.label :build_allow_git_fetch do
= f.radio_button :build_allow_git_fetch, 'true'
%strong git fetch
%br
%span.descr Faster
.form-group
= f.label :build_timeout_in_minutes, 'Timeout', class: 'control-label'
.col-sm-10
= f.number_field :build_timeout_in_minutes, class: 'form-control', min: '0'
%p.help-block per build in minutes
.form-group
= f.label :build_coverage_regex, "Test coverage parsing", class: 'control-label'
.col-sm-10
.input-group
%span.input-group-addon /
= f.text_field :build_coverage_regex, class: 'form-control', placeholder: '\(\d+.\d+\%\) covered'
%span.input-group-addon /
%p.help-block
We will use this regular expression to find test coverage output in build trace.
Leave blank if you want to disable this feature
.bs-callout.bs-callout-info
%p Below are examples of regex for existing tools:
%ul
%li
Simplecov (Ruby) -
%code \(\d+.\d+\%\) covered
%li
pytest-cov (Python) -
%code \d+\%\s*$
%li
phpunit --coverage-text --colors=never (PHP) -
%code ^\s*Lines:\s*\d+.\d+\%
%fieldset.features
%legend
Advanced settings
.form-group
= f.label :token, "CI token", class: 'control-label'
.col-sm-10
= f.text_field :token, class: "form-control", placeholder: 'xEeFCaDAB89'
%p.help-block The secure token used to checkout project.
.form-actions
= f.submit 'Save changes', class: "btn btn-save"

View file

@ -1,20 +1,19 @@
- ci_project = @project.gitlab_ci_project
%h4 Overall stats
%ul
%li
Total:
%strong= pluralize ci_project.builds.count(:all), 'build'
%strong= pluralize @project.ci_builds.count(:all), 'build'
%li
Successful:
%strong= pluralize ci_project.builds.success.count(:all), 'build'
%strong= pluralize @project.ci_builds.success.count(:all), 'build'
%li
Failed:
%strong= pluralize ci_project.builds.failed.count(:all), 'build'
%strong= pluralize @project.ci_builds.failed.count(:all), 'build'
%li
Success ratio:
%strong
#{success_ratio(ci_project.builds.success, ci_project.builds.failed)}%
#{success_ratio(@project.ci_builds.success, @project.ci_builds.failed)}%
%li
Commits covered:
%strong
= ci_project.commits.count(:all)
= @project.ci_commits.count(:all)

View file

@ -15,10 +15,10 @@
- if runner.belongs_to_one_project?
= link_to 'Remove runner', runner_path(runner), data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-danger btn-sm'
- else
- runner_project = @ci_project.runner_projects.find_by(runner_id: runner)
= link_to 'Disable for this project', [:ci, @ci_project, runner_project], data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-danger btn-sm'
- runner_project = @project.ci_runner_projects.find_by(runner_id: runner)
= link_to 'Disable for this project', namespace_project_runner_project_path(@project.namespace, @project, runner_project), data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-danger btn-sm'
- elsif runner.specific?
= form_for [:ci, @ci_project, @ci_project.runner_projects.new] do |f|
= form_for [@project.namespace, @project, @project.ci_runner_projects.new] do |f|
= f.hidden_field :runner_id, value: runner.id
= f.submit 'Enable for this project', class: 'btn btn-sm'
.pull-right

View file

@ -3,11 +3,11 @@
.bs-callout.bs-callout-warning
GitLab Runners do not offer secure isolation between projects that they do builds for. You are TRUSTING all GitLab users who can push code to project A, B or C to run shell scripts on the machine hosting runner X.
%hr
- if @ci_project.shared_runners_enabled
= link_to toggle_shared_runners_ci_project_path(@ci_project), class: 'btn btn-warning', method: :post do
- if @project.shared_runners_enabled?
= link_to toggle_shared_runners_namespace_project_runners_path(@project.namespace, @project), class: 'btn btn-warning', method: :post do
Disable shared runners
- else
= link_to toggle_shared_runners_ci_project_path(@ci_project), class: 'btn btn-success', method: :post do
= link_to toggle_shared_runners_namespace_project_runners_path(@project.namespace, @project), class: 'btn btn-success', method: :post do
Enable shared runners
&nbsp; for this project

View file

@ -12,7 +12,7 @@
%code #{ci_root_url(only_path: false)}
%li
Use the following registration token during setup:
%code #{@ci_project.token}
%code #{@project.token}
%li
Start runner!

View file

@ -36,7 +36,7 @@
:plain
curl -X POST \
-F token=TOKEN \
#{ci_build_trigger_url(@ci_project.id, 'REF_NAME')}
#{ci_build_trigger_url(@project.id, 'REF_NAME')}
%h3
Use .gitlab-ci.yml
@ -51,7 +51,7 @@
trigger:
type: deploy
script:
- "curl -X POST -F token=TOKEN #{ci_build_trigger_url(@ci_project.id, 'REF_NAME')}"
- "curl -X POST -F token=TOKEN #{ci_build_trigger_url(@project.id, 'REF_NAME')}"
%h3
Pass build variables
@ -66,4 +66,4 @@
curl -X POST \
-F token=TOKEN \
-F "variables[RUN_NIGHTLY_BUILD]=true" \
#{ci_build_trigger_url(@ci_project.id, 'REF_NAME')}
#{ci_build_trigger_url(@project.id, 'REF_NAME')}

View file

@ -10,16 +10,16 @@
%hr
= nested_form_for @ci_project, url: url_for(controller: 'projects/variables', action: 'update'), html: { class: 'form-horizontal' } do |f|
= nested_form_for @project, url: url_for(controller: 'projects/variables', action: 'update'), html: { class: 'form-horizontal' } do |f|
- if @project.errors.any?
#error_explanation
%p.lead= "#{pluralize(@ci_project.errors.count, "error")} prohibited this project from being saved:"
%p.lead= "#{pluralize(@project.errors.count, "error")} prohibited this project from being saved:"
.alert.alert-error
%ul
- @ci_project.errors.full_messages.each do |msg|
- @project.errors.full_messages.each do |msg|
%li= msg
= f.fields_for :variables do |variable_form|
= f.fields_for :ci_variables do |variable_form|
.form-group
= variable_form.label :key, 'Key', class: 'control-label'
.col-sm-10
@ -34,7 +34,7 @@
%hr
%p
.clearfix
= f.link_to_add "Add a variable", :variables, class: 'btn btn-success pull-right'
= f.link_to_add "Add a variable", :ci_variables, class: 'btn btn-success pull-right'
.form-actions
= f.submit 'Save changes', class: 'btn btn-save', return_to: request.original_url

View file

@ -24,43 +24,10 @@ Rails.application.routes.draw do
resource :lint, only: [:show, :create]
resources :projects do
collection do
post :add
get :disabled
end
member do
get :status, to: 'projects#badge'
get :integration
post :toggle_shared_runners
end
resources :runner_projects, only: [:create, :destroy]
end
resource :user_sessions do
get :auth
get :callback
end
namespace :admin do
resources :runners, only: [:index, :show, :update, :destroy] do
member do
put :assign_all
get :resume
get :pause
end
end
resources :events, only: [:index]
resources :projects do
resources :runner_projects
end
resources :builds, only: :index
resource :application_settings, only: [:show, :update]
end
root to: 'projects#index'
@ -271,6 +238,8 @@ Rails.application.routes.draw do
member do
put :transfer
end
resources :runner_projects
end
end
@ -280,6 +249,19 @@ Rails.application.routes.draw do
resources :labels
resources :runners, only: [:index, :show, :update, :destroy] do
member do
get :resume
get :pause
end
end
resources :builds, only: :index do
collection do
post :cancel_all
end
end
root to: 'dashboard#index'
end
@ -595,7 +577,6 @@ Rails.application.routes.draw do
resources :protected_branches, only: [:index, :create, :update, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex }
resource :variables, only: [:show, :update]
resources :triggers, only: [:index, :create, :destroy]
resource :ci_settings, only: [:edit, :update, :destroy]
resources :builds, only: [:index, :show] do
collection do
@ -674,7 +655,13 @@ Rails.application.routes.draw do
get :resume
get :pause
end
collection do
post :toggle_shared_runners
end
end
resources :runner_projects, only: [:create, :destroy]
end
end
end

View file

@ -0,0 +1,10 @@
class AddCiToProject < ActiveRecord::Migration
def up
add_column :projects, :builds_enabled, :boolean, default: true, null: false
add_column :projects, :shared_runners_enabled, :boolean, default: true, null: false
add_column :projects, :token, :string
add_column :projects, :build_coverage_regex, :string
add_column :projects, :build_allow_git_fetch, :boolean, default: true, null: false
add_column :projects, :build_timeout, :integer, default: 3600, null: false
end
end

View file

@ -0,0 +1,8 @@
class AddProjectIdToCi < ActiveRecord::Migration
def up
add_column :ci_builds, :gl_project_id, :integer
add_column :ci_runner_projects, :gl_project_id, :integer
add_column :ci_triggers, :gl_project_id, :integer
add_column :ci_variables, :gl_project_id, :integer
end
end

View file

@ -0,0 +1,36 @@
class MigrateCiToProject < ActiveRecord::Migration
def up
migrate_project_id_for_table('ci_runner_projects')
migrate_project_id_for_table('ci_triggers')
migrate_project_id_for_table('ci_variables')
migrate_project_id_for_builds
migrate_project_column('shared_runners_enabled')
migrate_project_column('token')
migrate_project_column('coverage_regex', 'build_coverage_regex')
migrate_project_column('allow_git_fetch', 'build_allow_git_fetch')
migrate_project_column('timeout', 'build_timeout')
migrate_ci_service
end
def migrate_project_id_for_table(table)
subquery = "SELECT gitlab_id FROM ci_projects WHERE ci_projects.id = #{table}.project_id"
execute("UPDATE #{table} SET gl_project_id=(#{subquery}) WHERE gl_project_id IS NULL")
end
def migrate_project_id_for_builds
subquery = 'SELECT gl_project_id FROM ci_commits WHERE ci_commits.id = ci_builds.commit_id'
execute("UPDATE ci_builds SET gl_project_id=(#{subquery}) WHERE gl_project_id IS NULL")
end
def migrate_project_column(column, new_column = nil)
new_column ||= column
subquery = "SELECT #{column} FROM ci_projects WHERE projects.id = ci_projects.gitlab_id"
execute("UPDATE projects SET #{new_column}=(#{subquery}) WHERE #{new_column} IS NULL AND (#{subquery}) IS NOT NULL")
end
def migrate_ci_service
subquery = "SELECT active FROM services WHERE projects.id = services.project_id AND type='GitlabCiService'"
execute("UPDATE projects SET builds_enabled=(#{subquery}) WHERE builds_enabled IS NULL AND (#{subquery}) IS NOT NULL")
end
end

View file

@ -0,0 +1,11 @@
class AddIndexToCiTables < ActiveRecord::Migration
def up
add_index :ci_builds, :gl_project_id
add_index :ci_runner_projects, :gl_project_id
add_index :ci_triggers, :gl_project_id
add_index :ci_variables, :gl_project_id
add_index :projects, :token
add_index :projects, :builds_enabled
add_index :projects, [:builds_enabled, :shared_runners_enabled]
end
end

Some files were not shown because too many files have changed in this diff Show more