#37: merge master into branch

This commit is contained in:
Vokhmin Alexey V 2013-03-25 19:16:06 +04:00
commit 79f428f6d2
22 changed files with 136 additions and 35 deletions

View File

@ -982,6 +982,10 @@ table.diff {
} }
/* Mass build forms */ /* Mass build forms */
.mass-build-actions a.button {
margin-bottom: 5px;
}
form.mass_build input[type="checkbox"] { form.mass_build input[type="checkbox"] {
width: 10px; width: 10px;
height: 11px; height: 11px;
@ -1537,6 +1541,10 @@ table.tablesorter.platform-maintainers.static-search thead tr.search th input[ty
width: 430px; width: 430px;
} }
.tablesorter .right {
text-align: right;
}
.all_platforms { .all_platforms {
> .both { margin: 0 0 5px; } > .both { margin: 0 0 5px; }
.build_for_pl { font-weight: bold; } .build_for_pl { font-weight: bold; }

View File

@ -6,8 +6,8 @@ class Platforms::MassBuildsController < Platforms::BaseController
load_and_authorize_resource load_and_authorize_resource
skip_load_and_authorize_resource :only => [:index, :create] skip_load_and_authorize_resource :only => [:index, :create]
skip_load_and_authorize_resource :platform, :only => [:cancel, :failed_builds_list] skip_load_and_authorize_resource :platform, :only => [:cancel, :failed_builds_list, :publish]
skip_authorize_resource :platform, :only => [:create, :index] skip_authorize_resource :platform, :only => [:index, :create]
def create def create
mass_build = @platform.mass_builds.new(:arches => params[:arches], mass_build = @platform.mass_builds.new(:arches => params[:arches],
@ -27,6 +27,15 @@ class Platforms::MassBuildsController < Platforms::BaseController
end end
end end
def publish
if params[:status] == 'test_failed'
@mass_build.publish_test_faild_builds
else
@mass_build.publish_success_builds
end
redirect_to(platform_mass_builds_path(@mass_build.platform), :notice => t("flash.platform.publish_success"))
end
def index def index
authorize! :local_admin_manage, @platform authorize! :local_admin_manage, @platform

View File

@ -98,7 +98,7 @@ class Ability
can([:update, :destroy], Platform) {|platform| owner?(platform) } can([:update, :destroy], Platform) {|platform| owner?(platform) }
can([:local_admin_manage, :members, :add_member, :remove_member, :remove_members] , Platform) {|platform| owner?(platform) || local_admin?(platform) } can([:local_admin_manage, :members, :add_member, :remove_member, :remove_members] , Platform) {|platform| owner?(platform) || local_admin?(platform) }
can([:get_list, :create], MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && mass_build.platform.main?} can([:get_list, :create, :publish], MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && mass_build.platform.main?}
can(:cancel, MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && !mass_build.stop_build && mass_build.platform.main?} can(:cancel, MassBuild) {|mass_build| (owner?(mass_build.platform) || local_admin?(mass_build.platform)) && !mass_build.stop_build && mass_build.platform.main?}
can [:read, :projects_list, :projects], Repository, :platform => {:owner_type => 'User', :owner_id => user.id} can [:read, :projects_list, :projects], Repository, :platform => {:owner_type => 'User', :owner_id => user.id}
@ -158,7 +158,7 @@ class Ability
cannot :create_container, BuildList, :new_core => false cannot :create_container, BuildList, :new_core => false
cannot(:publish, BuildList) {|build_list| !build_list.can_publish? } cannot(:publish, BuildList) {|build_list| !build_list.can_publish? }
cannot([:get_list, :create], MassBuild) {|mass_build| mass_build.platform.personal?} cannot([:get_list, :create, :publish], MassBuild) {|mass_build| mass_build.platform.personal?}
cannot(:cancel, MassBuild) {|mass_build| mass_build.platform.personal? || mass_build.stop_build} cannot(:cancel, MassBuild) {|mass_build| mass_build.platform.personal? || mass_build.stop_build}
cannot(:regenerate_metadata, Repository) {|repository| !repository.platform.main?} cannot(:regenerate_metadata, Repository) {|repository| !repository.platform.main?}

View File

@ -28,7 +28,7 @@ class MassBuild < ActiveRecord::Base
def build_all def build_all
# later with resque # later with resque
arches_list = arches ? Arch.where(:id => arches) : Arch.all arches_list = arch_names ? Arch.where(:name => arch_names.split(', ')) : Arch.all
auto_publish ||= false auto_publish ||= false
projects_list.lines.each do |name| projects_list.lines.each do |name|
@ -70,8 +70,24 @@ class MassBuild < ActiveRecord::Base
end end
later :cancel_all, :queue => :clone_build later :cancel_all, :queue => :clone_build
def publish_success_builds
publish BuildList::SUCCESS, BuildList::FAILED_PUBLISH
end
later :publish_success_builds, :queue => :clone_build
def publish_test_faild_builds
publish BuildList::TESTS_FAILED
end
later :publish_test_faild_builds, :queue => :clone_build
private private
def publish(*statuses)
build_lists.where(:status => statuses).order(:id).find_in_batches(:batch_size => 50) do |bls|
bls.each{ |bl| bl.can_publish? && bl.now_publish }
end
end
def set_data def set_data
if new_record? if new_record?
self.name = "#{Time.now.utc.to_date.strftime("%d.%b")}-#{platform.name}" self.name = "#{Time.now.utc.to_date.strftime("%d.%b")}-#{platform.name}"

View File

@ -34,7 +34,8 @@ class ProductBuildList < ActiveRecord::Base
belongs_to :arch belongs_to :arch
belongs_to :user belongs_to :user
# see: Issue #6
before_validation lambda { self.arch_id = Arch.find_by_name('x86_64').id }
validates :product_id, validates :product_id,
:status, :status,
:project_id, :project_id,
@ -52,7 +53,6 @@ class ProductBuildList < ActiveRecord::Base
:params, :params,
:project_version, :project_version,
:commit_hash, :commit_hash,
:arch_id,
:product_id :product_id
attr_readonly :product_id attr_readonly :product_id
serialize :results, Array serialize :results, Array

View File

@ -78,12 +78,17 @@ class PullRequest < ActiveRecord::Base
def merge!(who) def merge!(who)
return false unless can_merging? return false unless can_merging?
Dir.chdir(path) do Dir.chdir(path) do
old_commit = to_project.repo.commits(to_ref).first
commit = repo.commits(to_ref).first commit = repo.commits(to_ref).first
system "git config user.name \"#{who.uname}\" && git config user.email \"#{who.email}\"" system "git config user.name \"#{who.uname}\" && git config user.email \"#{who.email}\""
res = merge res = merge
if commit.id != repo.commits(to_ref).first.id if commit.id != repo.commits(to_ref).first.id
system("export GL_ID=user-#{who.id} && git push origin HEAD") res2 = %x(export GL_ID=user-#{who.id} && git push origin HEAD)
system("git reset --hard HEAD^") # for diff maybe FIXME system("git reset --hard HEAD^") # for diff maybe FIXME
if old_commit.id == to_project.repo.commits(to_ref).first.id
raise "merge result pull_request #{id}: #{$?.exitstatus}; #{res2}; #{res}"
end
set_user_and_time who set_user_and_time who
merging merging
else # Try to catch no merge errors else # Try to catch no merge errors

View File

@ -12,10 +12,6 @@ json.product_build_list do |json|
:project => @product_build_list.project, :json => json_project :project => @product_build_list.project, :json => json_project
end end
json.arch do |json_arch|
json_arch.(@product_build_list.arch, :id, :name)
end
json.created_at @product_build_list.created_at.to_i json.created_at @product_build_list.created_at.to_i
json.updated_at @product_build_list.updated_at.to_i json.updated_at @product_build_list.updated_at.to_i

View File

@ -27,7 +27,7 @@
%th.lpadding16= t('activerecord.attributes.mass_build.name') %th.lpadding16= t('activerecord.attributes.mass_build.name')
%th.lpadding16= t("layout.mass_builds.statuses") %th.lpadding16= t("layout.mass_builds.statuses")
%th.lpadding16= t("layout.mass_builds.failed_builds_list") %th.lpadding16= t("layout.mass_builds.failed_builds_list")
%th.lpadding16= t("layout.mass_builds.cancel_mass_build") %th.lpadding16= t("layout.mass_builds.actions")
%th.lpadding16= t("layout.mass_builds.extended_data") %th.lpadding16= t("layout.mass_builds.extended_data")
- @mass_builds.each do |mass_build| - @mass_builds.each do |mass_build|
%tr %tr
@ -43,7 +43,20 @@
= mass_build.read_attribute 'missed_projects_count' = mass_build.read_attribute 'missed_projects_count'
%td %td
=link_to_list @platform, mass_build, 'failed_builds_list' =link_to_list @platform, mass_build, 'failed_builds_list'
%td= link_to image_tag('x.png'), cancel_platform_mass_build_path(@platform, mass_build.id), :method => :post, :confirm => t("layout.mass_builds.cancel_confirm") if can?(:cancel, mass_build) %td.right.mass-build-actions
- if can?(:publish, mass_build)
- unless mass_build.auto_publish?
= link_to t('layout.mass_builds.publish_success'),
publish_platform_mass_build_path(@platform, mass_build.id),
:method => :post, :confirm => t("layout.confirm"), :class => 'button'
= link_to t('layout.mass_builds.publish_test_failed'),
publish_platform_mass_build_path(@platform, mass_build.id, :status => 'test_failed'),
:method => :post, :confirm => t("layout.confirm"), :class => 'button'
- if can?(:cancel, mass_build)
= link_to t('layout.cancel'),
cancel_platform_mass_build_path(@platform, mass_build.id),
:method => :post, :class => 'button',
:confirm => t('layout.mass_builds.cancel_confirm')
%td %td
%a.toggle_btn{:href => "#toggle_#{ mass_build.id }", :'data-target' => "#toggle_#{ mass_build.id }"}= t("layout.mass_builds.extended_data") %a.toggle_btn{:href => "#toggle_#{ mass_build.id }", :'data-target' => "#toggle_#{ mass_build.id }"}= t("layout.mass_builds.extended_data")
.toggle{:id => "toggle_#{ mass_build.id }"} .toggle{:id => "toggle_#{ mass_build.id }"}

View File

@ -12,10 +12,6 @@
.rightlist= f.select :project_version, versions_for_group_select(pbl.project), :selected => params[:product_build_lists].try(:fetch, :project_version) || pbl.project.default_branch .rightlist= f.select :project_version, versions_for_group_select(pbl.project), :selected => params[:product_build_lists].try(:fetch, :project_version) || pbl.project.default_branch
.both .both
.leftlist= f.label :arch, t("activerecord.attributes.product_build_list.arch"), :class => :label
.rightlist= f.select :arch_id, Arch.recent.map{ |a| [a.name, a.id]}
.both
= render 'platforms/products/def_fields', :f => f = render 'platforms/products/def_fields', :f => f
= f.submit t("layout.projects.build_button") = f.submit t("layout.projects.build_button")

View File

@ -19,7 +19,6 @@
= render 'show_field', :key => :project_version, :value => product_build_list_version_link(pbl, true) = render 'show_field', :key => :project_version, :value => product_build_list_version_link(pbl, true)
= render 'show_field', :key => :arch, :value => pbl.arch.name
- [:main_script, :params].each do |el| - [:main_script, :params].each do |el|
= render 'show_field', :key => el, :value => pbl.send(el) = render 'show_field', :key => el, :value => pbl.send(el)

View File

@ -1,11 +1,13 @@
en: en:
layout: layout:
mass_builds: mass_builds:
publish_success: Publish success builds
publish_test_failed: Publish test failed builds
repositories: Repositories repositories: Repositories
extended_data: Extended data extended_data: Extended data
failed_builds_list: Failed Builds List failed_builds_list: Failed Builds List
statuses: Statuses statuses: Statuses
cancel_mass_build: Cancel actions: Actions
cancel_confirm: Are you sure you want to cancel mass build? cancel_confirm: Are you sure you want to cancel mass build?
projects_list: Projects list projects_list: Projects list
missed_projects_list: 'Missed projects: ' missed_projects_list: 'Missed projects: '

View File

@ -1,11 +1,13 @@
ru: ru:
layout: layout:
mass_builds: mass_builds:
publish_success: Опубликовать успешные сборки
publish_test_failed: Опубликовать сборки с проваленными тестами
repositories: Репозитории repositories: Репозитории
extended_data: Параметры задания extended_data: Параметры задания
failed_builds_list: Список ошибок сборок failed_builds_list: Список ошибок сборок
statuses: Статусы statuses: Статусы
cancel_mass_build: Отмена actions: Действия
cancel_confirm: Вы уверены, что хотите отменить массовую сборку? cancel_confirm: Вы уверены, что хотите отменить массовую сборку?
projects_list: Список проектов projects_list: Список проектов
missed_projects_list: 'Несуществующие проекты: ' missed_projects_list: 'Несуществующие проекты: '

View File

@ -62,6 +62,7 @@ en:
build_all_success: All project build in progress build_all_success: All project build in progress
build_all_error: Mass build failed build_all_error: Mass build failed
cancel_mass_build: Mass build canceled cancel_mass_build: Mass build canceled
publish_success: Builds have been sent to queue for publishing successfully
clone_success: Cloned successfully clone_success: Cloned successfully
members: members:
successfully_added: "%{name} successfully added to the platform" successfully_added: "%{name} successfully added to the platform"

View File

@ -62,6 +62,7 @@ ru:
build_all_success: Все проекты успешно отправлены на сборку build_all_success: Все проекты успешно отправлены на сборку
build_all_error: Сборка не удалась! build_all_error: Сборка не удалась!
cancel_mass_build: Массовая сборка отменена cancel_mass_build: Массовая сборка отменена
publish_success: Сборки успешно отправлены в очередь на публикацию
clone_success: Клонирование успешно clone_success: Клонирование успешно
members: members:
successfully_added: "Участник %{name} успешно добавлен к платформе" successfully_added: "Участник %{name} успешно добавлен к платформе"

View File

@ -145,6 +145,7 @@ Rosa::Application.routes.draw do
resources :mass_builds, :only => [:create, :index] do resources :mass_builds, :only => [:create, :index] do
member do member do
post :cancel post :cancel
post :publish
get '/:kind.:format' => "mass_builds#get_list", :as => :get_list, :kind => /failed_builds_list|missed_projects_list|projects_list/ get '/:kind.:format' => "mass_builds#get_list", :as => :get_list, :kind => /failed_builds_list|missed_projects_list|projects_list/
end end
end end

View File

@ -32,7 +32,7 @@ module AbfWorker
def sort_results_and_save(results, item = subject) def sort_results_and_save(results, item = subject)
item.results = results.sort_by{ |r| r['file_name'] } item.results = results.sort_by{ |r| r['file_name'] }
item.save! item.save(:validate => false)
end end
end end

View File

@ -228,6 +228,17 @@ module AbfWorker
end end
def create_rpm_build_task(save_to_repository_id, build_for_platform_id) def create_rpm_build_task(save_to_repository_id, build_for_platform_id)
projects_for_cleanup = @redis.lrange(PROJECTS_FOR_CLEANUP, 0, -1).
select{ |k| k =~ /#{save_to_repository_id}\-#{build_for_platform_id}$/ }
# We should not to publish new builds into repository
# if project of builds has been removed from repository.
BuildList.where(
:project_id => projects_for_cleanup.map{ |k| k.split('-')[0] }.uniq,
:save_to_repository_id => save_to_repository_id,
:status => BuildList::BUILD_PUBLISH
).update_all(:status => BuildList::FAILED_PUBLISH)
build_lists = BuildList. build_lists = BuildList.
where(:new_core => true, :status => BuildList::BUILD_PUBLISH). where(:new_core => true, :status => BuildList::BUILD_PUBLISH).
where(:save_to_repository_id => save_to_repository_id). where(:save_to_repository_id => save_to_repository_id).
@ -237,9 +248,6 @@ module AbfWorker
build_lists = build_lists.where('build_lists.id NOT IN (?)', locked_ids) unless locked_ids.empty? build_lists = build_lists.where('build_lists.id NOT IN (?)', locked_ids) unless locked_ids.empty?
build_lists = build_lists.limit(50) build_lists = build_lists.limit(50)
projects_for_cleanup = @redis.lrange(PROJECTS_FOR_CLEANUP, 0, -1).
select{ |k| k =~ /#{save_to_repository_id}\-#{build_for_platform_id}$/ }
old_packages = {:sources => [], :binaries => {:x86_64 => [], :i586 => []}} old_packages = {:sources => [], :binaries => {:x86_64 => [], :i586 => []}}
projects_for_cleanup.each do |key| projects_for_cleanup.each do |key|

View File

@ -36,9 +36,10 @@ module AbfWorker
update_results build_list update_results build_list
case status case status
when COMPLETED when COMPLETED
build_list.published # 'update_column' - when project of build_list has been removed from repository
build_list.published || build_list.update_column(:status, BuildList::BUILD_PUBLISHED)
when FAILED, CANCELED when FAILED, CANCELED
build_list.fail_publish build_list.fail_publish || build_list.update_column(:status, BuildList::FAILED_PUBLISH)
end end
AbfWorker::BuildListsPublishTaskManager.unlock_build_list build_list AbfWorker::BuildListsPublishTaskManager.unlock_build_list build_list
end end

View File

@ -1,5 +1,14 @@
# -*- encoding : utf-8 -*- # -*- encoding : utf-8 -*-
module Grit module Grit
class Commit
# Fix: NoMethodError: undefined method 'touch' for Grit::Commit
# see: model Comment belongs_to :commentable
def touch
true
end
end
class Blob class Blob
include Linguist::BlobHelper include Linguist::BlobHelper

View File

@ -22,6 +22,16 @@ shared_examples_for 'mass_build platform owner' do
@mass_build.reload.stop_build.should == true @mass_build.reload.stop_build.should == true
end end
it 'should be able to perform publish action' do
post :publish, :platform_id => @platform, :id => @mass_build
response.should redirect_to(platform_mass_builds_path(@platform))
end
it 'should change build_publish on publish' do
post :publish, :platform_id => @platform, :id => @mass_build
@mass_build.reload.build_publish_count.should == 1
end
it 'should not be able to perform cancel action if stop_build is true' do it 'should not be able to perform cancel action if stop_build is true' do
@mass_build.stop_build = true; @mass_build.save @mass_build.stop_build = true; @mass_build.save
post :cancel, :platform_id => @platform, :id => @mass_build post :cancel, :platform_id => @platform, :id => @mass_build
@ -34,10 +44,10 @@ shared_examples_for 'mass_build platform owner' do
context 'for personal platform' do context 'for personal platform' do
before(:each) do before(:each) do
Platform.update_all("platform_type = 'personal'") Platform.update_all(:platform_type => 'personal')
end end
[:cancel, :get_list, :create].each do |action| [:cancel, :get_list, :create, :publish].each do |action|
it "should not be able to perform #{ action } action" do it "should not be able to perform #{ action } action" do
get action, :platform_id => @platform, :id => @mass_build.id get action, :platform_id => @platform, :id => @mass_build.id
response.should redirect_to(forbidden_path) response.should redirect_to(forbidden_path)
@ -54,7 +64,7 @@ shared_examples_for 'mass_build platform reader' do
end end
end end
[:cancel, :get_list].each do |action| [:cancel, :get_list, :publish].each do |action|
it "should not be able to perform #{ action } action" do it "should not be able to perform #{ action } action" do
get action, :platform_id => @platform, :id => @mass_build.id get action, :platform_id => @platform, :id => @mass_build.id
response.should redirect_to(forbidden_path) response.should redirect_to(forbidden_path)
@ -69,6 +79,11 @@ shared_examples_for 'mass_build platform reader' do
post :cancel, :platform_id => @platform, :id => @mass_build post :cancel, :platform_id => @platform, :id => @mass_build
@mass_build.reload.stop_build.should == false @mass_build.reload.stop_build.should == false
end end
it 'should not change build_publish on publish' do
post :publish, :platform_id => @platform, :id => @mass_build
@mass_build.reload.build_publish_count.should == 0
end
end end
@ -92,6 +107,7 @@ describe Platforms::MassBuildsController do
} }
@mass_build = FactoryGirl.create(:mass_build, :platform => @platform, :user => @user, :projects_list => project.name) @mass_build = FactoryGirl.create(:mass_build, :platform => @platform, :user => @user, :projects_list => project.name)
FactoryGirl.create(:build_list_core, :mass_build => @mass_build, :status => BuildList::SUCCESS)
end end
context 'for guest' do context 'for guest' do
@ -107,9 +123,11 @@ describe Platforms::MassBuildsController do
response.should redirect_to(new_user_session_path) response.should redirect_to(new_user_session_path)
end end
it "should not be able to perform cancel action" do [:cancel, :publish].each do |action|
post :cancel, :platform_id => @platform, :id => @mass_build it "should not be able to perform #{action} action" do
response.should redirect_to(new_user_session_path) post action, :platform_id => @platform, :id => @mass_build
response.should redirect_to(new_user_session_path)
end
end end
it 'should not change objects count on create success' do it 'should not change objects count on create success' do
@ -120,6 +138,12 @@ describe Platforms::MassBuildsController do
post :cancel, :platform_id => @platform, :id => @mass_build post :cancel, :platform_id => @platform, :id => @mass_build
@mass_build.reload.stop_build.should == false @mass_build.reload.stop_build.should == false
end end
it 'should not change build_publish_count on publish' do
post :publish, :platform_id => @platform, :id => @mass_build
@mass_build.reload.build_publish_count.should == 0
end
end end
context 'for global admin' do context 'for global admin' do

View File

@ -9,5 +9,8 @@ FactoryGirl.define do
params 'ENV=i586' params 'ENV=i586'
time_living 150 time_living 150
project_version 'master' project_version 'master'
# see: before_validation in ProductBuildList model
before(:create) { Arch.find_or_create_by_name('x86_64') }
end end
end end

View File

@ -186,11 +186,18 @@ describe AbfWorker::BuildListsPublishTaskManager do
:save_to_repository => build_list.save_to_repository, :save_to_repository => build_list.save_to_repository,
:build_for_platform => build_list.build_for_platform :build_for_platform => build_list.build_for_platform
) } ) }
let(:build_list3) { FactoryGirl.create(:build_list_core,
:new_core => true,
:save_to_platform => build_list.save_to_platform,
:save_to_repository => build_list.save_to_repository,
:build_for_platform => build_list.build_for_platform
) }
before do before do
stub_redis stub_redis
build_list.update_column(:status, BuildList::BUILD_PUBLISH) build_list.update_column(:status, BuildList::BUILD_PUBLISH)
build_list2.update_column(:status, BuildList::BUILD_PUBLISHED) build_list2.update_column(:status, BuildList::BUILD_PUBLISHED)
ProjectToRepository.where(:project_id => build_list.project_id, :repository_id => build_list.save_to_repository_id).destroy_all build_list3.update_column(:status, BuildList::BUILD_PUBLISHED)
ProjectToRepository.where(:project_id => build_list3.project_id, :repository_id => build_list3.save_to_repository_id).destroy_all
2.times{ subject.new.run } 2.times{ subject.new.run }
end end
@ -212,7 +219,7 @@ describe AbfWorker::BuildListsPublishTaskManager do
it "ensure that 'locked projects for cleanup' has only one item" do it "ensure that 'locked projects for cleanup' has only one item" do
queue = @redis_instance.lrange(subject::LOCKED_PROJECTS_FOR_CLEANUP, 0, -1) queue = @redis_instance.lrange(subject::LOCKED_PROJECTS_FOR_CLEANUP, 0, -1)
queue.should have(1).item queue.should have(1).item
queue.should include("#{build_list.project_id}-#{build_list.save_to_repository_id}-#{build_list.build_for_platform_id}") queue.should include("#{build_list3.project_id}-#{build_list3.save_to_repository_id}-#{build_list3.build_for_platform_id}")
end end
it "ensure that new task for publishing has been created" do it "ensure that new task for publishing has been created" do