Merge branch 'master' into 135-reject_build_lists

Conflicts:
	spec/controllers/api/v1/build_lists_controller_spec.rb
	spec/controllers/projects/build_lists_controller_spec.rb
This commit is contained in:
Alexander Machehin 2013-06-09 20:28:22 +06:00
commit 1db7955e0c
49 changed files with 536 additions and 427 deletions

View File

@ -52,7 +52,7 @@ GEM
activesupport (3.2.13)
i18n (= 0.6.1)
multi_json (~> 1.0)
airbrake (3.1.9)
airbrake (3.1.12)
activesupport
builder
json
@ -168,7 +168,7 @@ GEM
jquery-rails (2.0.3)
railties (>= 3.1.0, < 5.0)
thor (~> 0.14)
json (1.7.7)
json (1.8.0)
jwt (0.1.8)
multi_json (>= 1.5)
kgio (2.8.0)
@ -198,7 +198,7 @@ GEM
mocha (0.13.3)
metaclass (~> 0.0.1)
mock_redis (0.6.2)
multi_json (1.7.2)
multi_json (1.7.5)
multipart-post (1.2.0)
mustache (0.99.4)
net-scp (1.1.0)

View File

@ -0,0 +1,46 @@
$(document).ready(function() {
$('.autocomplete-form .button.add').click(function() {
var form = $(this).parent();
var field = form.attr('field');
var subject = $('#' + field + '_field');
if (!subject.val()) { return false; }
var name = form.attr('subject_class') + '[' + field + ']' + '[]';
var path = $('#' + field + '_field_path').val();
var label = $('#' + field + '_field_label').val();
addDataToAutocompleteForm(form, path, label, name, subject.val());
form.find('.autocomplete').val('');
return false;
});
$(document).on('click', '.autocomplete-form .delete', function() {
$(this).parent().parent().remove();
});
$('.autocomplete-form .dialog').dialog({
autoOpen: false,
resizable: false,
width: 500
});
$('.autocomplete-form .icon-question-sign').click(function() {
var field = $(this).parent().attr('field');
var dialog = $('#' + field + '_dialog');
if (dialog.is(':visible')) { dialog.dialog('close'); } else { dialog.dialog('open'); }
});
});
function addDataToAutocompleteForm(form, path, label, name, value) {
var tr = '<tr>' +
'<td>' +
'<a href="' + path + '">' + label + '</a>' +
'</td>' +
'<td class="actions">' +
'<input name="' + name + '" type="hidden" value="' + value + '">' +
'<span class="delete"> </span>' +
'</td>' +
'</tr>';
form.find('table tbody').append($(tr));
}

View File

@ -9,17 +9,19 @@ $(document).ready(function() {
var build_platform = $('#build_for_pl_' + platform_id);
var all_repositories = $('.all_platforms input');
all_repositories.removeAttr('checked');
var use_save_to_repository = $('#build_list_use_save_to_repository');
var auto_create_container = $('#build_list_auto_create_container');
var extra_repos = $('.autocomplete-form.extra_repositories');
updateExtraReposAndBuildLists(platform_id);
$('.autocomplete-form table tbody').empty();
if (build_platform.size() == 0) {
all_repositories.removeAttr('disabled');
use_save_to_repository.removeAttr('disabled');
auto_create_container.removeAttr('checked');
addPersonalPlatformToExtraRepos(selected_option, extra_repos);
extra_repos.show();
} else {
updateExtraReposAndBuildLists();
use_save_to_repository.attr('disabled', 'disabled').attr('checked', 'checked');
all_repositories.attr('disabled', 'disabled');
extra_repos.hide();
var parent = build_platform.parent();
parent.find('input').removeAttr('disabled');
parent.find('input[rep_name="main"]').attr('checked', 'checked');
@ -35,32 +37,10 @@ $(document).ready(function() {
build_list_auto_publish.removeAttr('checked').attr('disabled', 'disabled');
auto_create_container.attr('checked', 'checked');
}
var path = '/build_lists/autocomplete_to_extra_repos_and_builds?platform_id=' + platform_id;
$('#extra_repos').attr('data-autocomplete', path);
});
$('#build_list_save_to_repository_id').trigger('change');
$('#extra-repos-and-build-lists #add').click(function() {
updateExtraReposAndBuildLists();
return false;
});
$(document).on('click', '#extra-repos-and-build-lists .delete', function() {
$(this)[0].parentElement.parentElement.remove();
});
$('#extra-repos-and-build-lists-dialog').dialog({
autoOpen: false,
resizable: false,
width: 500
});
$('#extra-repos-and-build-lists .icon-question-sign').click(function() {
var dialog = $('#extra-repos-and-build-lists-dialog');
if (dialog.is(':visible')) { dialog.dialog('close'); } else { dialog.dialog('open'); }
});
var ownership_btn = $('.btn.ownership');
ownership_btn.click(function() {
@ -97,14 +77,26 @@ $(document).ready(function() {
});
});
function updateExtraReposAndBuildLists() {
$.get("/build_lists/update_extra_repos_and_builds", $('#new_build_list').serialize())
.done(function(data) {
$("#extra-repos-and-build-lists table tbody").html(data);
function updateExtraReposAndBuildLists(save_to_platform_id) {
$.each($('.autocomplete-form'), function() {
var form = $(this);
var path = form.attr('path') + '?platform_id=' + save_to_platform_id;
form.find('.autocomplete').attr('data-autocomplete', path);
});
}
function addPersonalPlatformToExtraRepos(selected_option, extra_repos) {
var default_value = extra_repos.find('div[label="' + selected_option.text() + '"]');
if (default_value.length == 0) { return; }
addDataToAutocompleteForm(
extra_repos,
default_value.attr('path'),
default_value.attr('label'),
default_value.attr('name'),
default_value.attr('value')
);
}
function setBranchSelected(selected_option) {
var pl_name = selected_option.text().match(/([\w-.]+)\/[\w-.]+/)[1];
var bl_version_sel = $('#build_list_project_version');

View File

@ -1,5 +1,5 @@
$(document).ready(function() {
var projects_list = $('.form.mass_build #projects_list');
var projects_list = $('.form.mass_build #mass_build_projects_list');
var repositories = $(".form.mass_build .left input:checkbox");
repositories.click(function(){
if (this.checked){

View File

@ -571,6 +571,7 @@ table.tablesorter tr td.buttons a span.delete,
span.delete {
background: image-url('x.png') no-repeat 0 0 transparent;
width: 12px;
height: 12px;
display: inline-block;
cursor: pointer;
}
@ -1788,11 +1789,6 @@ table#myTable thead tr.search th form.button_to div input {
border: 1px solid #DDDDDD;
}
#extra-repos-and-build-lists {
width: 330px;
.actions { width: 15px; }
}
.semi {
opacity: 0.5;
}
@ -1843,18 +1839,23 @@ table#myTable thead tr.search th form.button_to div input {
margin-left: 10px;
}
#extra-repos-and-build-lists {
.autocomplete-form {
width: 330px;
.actions { width: 15px; }
h3 { display: inline-block; }
.tablesorter {
width: auto;
min-width: 250px;
}
}
#extra-repos-and-build-lists-dialog {
#extra_repositories_dialog, #extra_build_lists_dialog {
font-size: 12px;
text-align: left;
p { margin: 0; }
}
#ui-dialog-title-extra-repos-and-build-lists-dialog {
#ui-dialog-title-extra_repositories_dialog, #ui-dialog-title-extra_build_lists_dialog {
font-size: 14px;
}

View File

@ -5,7 +5,7 @@ class Api::V1::IssuesController < Api::V1::BaseController
before_filter :authenticate_user!
skip_before_filter :authenticate_user!, :only => [:show] if APP_CONFIG['anonymous_access']
load_and_authorize_resource :group, :only => :group_index
load_resource :group, :only => :group_index, :find_by => :id, :parent => false
load_resource :project
load_and_authorize_resource :issue, :through => :project, :find_by => :serial_id, :only => [:show, :update, :destroy, :create, :index]
@ -28,6 +28,7 @@ class Api::V1::IssuesController < Api::V1::BaseController
def group_index
project_ids = @group.projects.select('distinct projects.id').pluck(:id)
project_ids = Project.accessible_by(current_ability, :membered).where(:id => project_ids).uniq.pluck(:id)
@issues = Issue.where(:project_id => project_ids)
render_issues_list
end

View File

@ -2,6 +2,45 @@
class AutocompletesController < ApplicationController
before_filter :authenticate_user!
autocomplete :group, :uname
autocomplete :user, :uname
autocomplete :group, :uname
autocomplete :user, :uname
def autocomplete_extra_build_list
bl = BuildList.for_extra_build_lists(params[:term], current_ability, save_to_platform).first
results << { :id => bl.id,
:value => bl.id,
:label => "#{bl.id} (#{bl.project.name} - #{bl.arch.name})",
:path => build_list_path(bl)
} if bl
render json: results.to_json
end
def autocomplete_extra_repositories
# Only personal repositories can be attached to the build
Platform.includes(:repositories).personal.search(params[:term])
.accessible_by(current_ability, :read)
.search_order.limit(5).each do |platform|
platform.repositories.each do |repository|
label = "#{platform.name}/#{repository.name}"
results << { :id => repository.id,
:label => label,
:value => label,
:path => platform_repository_path(platform, repository)
}
end
end if save_to_platform.personal?
render json: results.to_json
end
protected
def save_to_platform
@save_to_platform ||= Platform.find(params[:platform_id])
end
def results
@results ||= []
end
end

View File

@ -1,30 +1,26 @@
#class MassBuildsController < ApplicationController
class Platforms::MassBuildsController < Platforms::BaseController
before_filter :authenticate_user!
skip_before_filter :authenticate_user!, :only => [:index, :get_list] if APP_CONFIG['anonymous_access']
load_and_authorize_resource :platform
load_and_authorize_resource
load_resource :platform
load_and_authorize_resource :through => :platform, :shallow => true
skip_load_and_authorize_resource :only => [:index, :create]
skip_load_and_authorize_resource :platform, :only => [:cancel, :failed_builds_list, :publish]
skip_authorize_resource :platform, :only => [:index, :create]
def new
end
def create
mass_build = @platform.mass_builds.new(:arches => params[:arches],
:auto_publish => params[:auto_publish] || false,
:projects_list => params[:projects_list])
mass_build.user = current_user
authorize! :create, mass_build
@mass_build = @platform.mass_builds.build params[:mass_build]
@mass_build.user = current_user
@mass_build.arches = params[:arches]
if mass_build.save
if @mass_build.save
redirect_to(platform_mass_builds_path(@platform), :notice => t("flash.platform.build_all_success"))
else
@auto_publish_selected = params[:auto_publish].present?
@mass_builds = MassBuild.by_platform(@platform).order('created_at DESC').paginate(:page => params[:page], :per_page => 20)
flash[:warning] = mass_build.errors.full_messages.join('. ')
flash[:error] = t("flash.platform.build_all_error")
render :index
flash[:warning] = @mass_build.errors.full_messages.join('. ')
flash[:error] = t('flash.platform.build_all_error')
render :action => :new
end
end
@ -34,26 +30,25 @@ class Platforms::MassBuildsController < Platforms::BaseController
else
@mass_build.publish_success_builds current_user
end
redirect_to(platform_mass_builds_path(@mass_build.platform), :notice => t("flash.platform.publish_success"))
redirect_to(platform_mass_builds_path(@mass_build.save_to_platform), :notice => t("flash.platform.publish_success"))
end
def index
@mass_builds = MassBuild.by_platform(@platform).order('created_at DESC').paginate(:page => params[:page], :per_page => 20)
@auto_publish_selected = true
@mass_builds = MassBuild.by_platform(@platform).order('created_at DESC').paginate(:page => params[:page], :per_page => 20)
end
def cancel
@mass_build.cancel_all
flash[:notice] = t("flash.platform.cancel_mass_build")
redirect_to platform_mass_builds_path(@mass_build.platform)
redirect_to platform_mass_builds_path(@mass_build.save_to_platform)
end
def get_list
text = if params[:kind] == 'failed_builds_list'
@mass_build.generate_failed_builds_list
elsif ['projects_list', 'missed_projects_list'].include? params[:kind]
@mass_build.send params[:kind]
end
text = if params[:kind] == 'failed_builds_list'
@mass_build.generate_failed_builds_list
elsif ['projects_list', 'missed_projects_list'].include? params[:kind]
@mass_build.send params[:kind]
end
render :text => text
end
end

View File

@ -34,7 +34,6 @@ class Projects::BuildListsController < Projects::BaseController
end
def new
# @build_list = BuildList.new # @build_list already created by CanCan
end
def create
@ -114,36 +113,6 @@ class Projects::BuildListsController < Projects::BaseController
}
end
def autocomplete_to_extra_repos_and_builds
results, save_to_platform = [], Platform.find(params[:platform_id])
bl = BuildList.where(:id => params[:term]).published_container.accessible_by(current_ability, :read)
if save_to_platform.main?
bl = bl.where(:save_to_platform_id => save_to_platform.id)
else
# Only personal repositories can be attached to the build
platforms = Platform.includes(:repositories).personal.search(params[:term]).
accessible_by(current_ability, :read).search_order.limit(5)
platforms.each{ |p| p.repositories.each{ |r| results << {:id => r.id, :label => "#{p.name}/#{r.name}", :value => "#{p.name}/#{r.name}"} } }
end
bl = bl.first
results << {:id => "#{bl.id}-build-list", :value => bl.id, :label => "#{bl.id} (#{bl.project.name} - #{bl.arch.name})"} if bl
render json: results.to_json
end
def update_extra_repos_and_builds
results, save_to_repository = [], Repository.find(params[:build_list][:save_to_repository_id])
extra_repos = params[:build_list][:extra_repositories] || []
extra_bls = params[:build_list][:extra_build_lists] || []
(params[:extra_repo].gsub!(/-build-list$/, '') ? extra_bls : extra_repos) << params[:extra_repo]
build_lists = BuildList.where(:id => extra_bls).published_container.accessible_by(current_ability, :read)
if save_to_repository.platform.main?
build_lists = build_lists.where(:save_to_platform_id => save_to_repository.platform_id)
else
results.concat Repository.where(:id => extra_repos).accessible_by(current_ability, :read)
end
render :partial => 'extra', :collection => results.concat(build_lists)
end
protected
def find_build_list

View File

@ -4,7 +4,7 @@ module BuildListsHelper
case status
when BuildList::BUILD_PUBLISHED, BuildList::SUCCESS
'success'
when BuildList::BUILD_ERROR, BuildList::PROJECT_VERSION_NOT_FOUND, BuildList::FAILED_PUBLISH, BuildList::REJECTED_PUBLISH
when BuildList::BUILD_ERROR, BuildList::FAILED_PUBLISH, BuildList::REJECTED_PUBLISH
'error'
when BuildList::TESTS_FAILED
'warning'

View File

@ -26,7 +26,7 @@ class Ability
# Platforms block
can [:show, :members, :advisories], Platform, :visibility => 'open'
can :platforms_for_build, Platform, :visibility => 'open', :platform_type => 'main'
can(:get_list, MassBuild) {|mass_build| mass_build.platform.main? && can?(:show, mass_build.platform) }
can([:read, :get_list], MassBuild) {|mass_build| can?(:show, mass_build.save_to_platform) }
can [:read, :projects_list, :projects], Repository, :platform => {:visibility => 'open'}
can :read, Product, :platform => {:visibility => 'open'}
@ -78,7 +78,6 @@ class Ability
can([:read, :create, :edit, :destroy, :update], Hook) {|hook| can?(:edit, hook.project)}
can [:autocomplete_to_extra_repos_and_builds, :update_extra_repos_and_builds], BuildList
can [:read, :log, :owned, :everything], BuildList, :user_id => user.id
can [:read, :log, :related, :everything], BuildList, :project => {:owner_type => 'User', :owner_id => user.id}
can [:read, :log, :related, :everything], BuildList, :project => {:owner_type => 'Group', :owner_id => user.group_ids}
@ -110,8 +109,8 @@ class Ability
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([: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([:create, :publish], MassBuild) {|mass_build| owner?(mass_build.save_to_platform) || local_admin?(mass_build.save_to_platform)}
can(:cancel, MassBuild) {|mass_build| (owner?(mass_build.save_to_platform) || local_admin?(mass_build.save_to_platform)) && !mass_build.stop_build}
can [:read, :projects_list, :projects], Repository, :platform => {:owner_type => 'User', :owner_id => user.id}
can [:read, :projects_list, :projects], Repository, :platform => {:owner_type => 'Group', :owner_id => user.group_ids}
@ -171,8 +170,7 @@ class Ability
cannot :create_container, BuildList, :new_core => false
cannot(:publish, BuildList) {|build_list| !build_list.can_publish? }
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.stop_build}
cannot(:regenerate_metadata, Repository) {|repository| !repository.platform.main?}

View File

@ -6,7 +6,6 @@ class ActivityFeedObserver < ActiveRecord::Observer
BuildList::BUILD_PUBLISHED,
BuildList::SUCCESS,
BuildList::BUILD_ERROR,
BuildList::PROJECT_VERSION_NOT_FOUND,
BuildList::FAILED_PUBLISH,
BuildList::TESTS_FAILED
].freeze

View File

@ -16,8 +16,8 @@ class BuildList < ActiveRecord::Base
has_many :items, :class_name => "BuildList::Item", :dependent => :destroy
has_many :packages, :class_name => "BuildList::Package", :dependent => :destroy
UPDATE_TYPES = %w[security bugfix enhancement recommended newpackage]
RELEASE_UPDATE_TYPES = %w[security bugfix]
UPDATE_TYPES = %w[bugfix security enhancement recommended newpackage]
RELEASE_UPDATE_TYPES = %w[bugfix security]
validates :project_id, :project_version, :arch, :include_repos,
:build_for_platform_id, :save_to_platform_id, :save_to_repository_id, :presence => true
@ -46,19 +46,16 @@ class BuildList < ActiveRecord::Base
before_validation :prepare_extra_repositories, :on => :create
before_validation :prepare_extra_build_lists, :on => :create
before_create :use_save_to_repository_for_main_platforms
attr_accessible :include_repos, :auto_publish, :build_for_platform_id, :commit_hash,
:arch_id, :project_id, :save_to_repository_id, :update_type,
:save_to_platform_id, :project_version, :use_save_to_repository,
:auto_create_container, :extra_repositories, :extra_build_lists
:save_to_platform_id, :project_version, :auto_create_container,
:extra_repositories, :extra_build_lists
LIVE_TIME = 4.week # for unpublished
MAX_LIVE_TIME = 3.month # for published
SUCCESS = 0
ERROR = 1
PROJECT_VERSION_NOT_FOUND = 4
PROJECT_SOURCE_ERROR = 6
DEPENDENCIES_ERROR = 555
BUILD_ERROR = 666
@ -84,7 +81,6 @@ class BuildList < ActiveRecord::Base
SUCCESS,
BUILD_STARTED,
BUILD_ERROR,
PROJECT_VERSION_NOT_FOUND,
TESTS_FAILED
].freeze
@ -99,11 +95,16 @@ class BuildList < ActiveRecord::Base
BUILD_ERROR => :build_error,
BUILD_STARTED => :build_started,
SUCCESS => :success,
PROJECT_VERSION_NOT_FOUND => :project_version_not_found,
TESTS_FAILED => :tests_failed
}.freeze
scope :recent, order("#{table_name}.updated_at DESC")
scope :for_extra_build_lists, lambda {|ids, current_ability, save_to_platform|
s = scoped
s = s.where(:id => ids).published_container.accessible_by(current_ability, :read)
s = s.where(:save_to_platform_id => save_to_platform.id) if save_to_platform && save_to_platform.main?
s
}
scope :for_status, lambda {|status| where(:status => status) }
scope :for_user, lambda { |user| where(:user_id => user.id) }
scope :for_platform, lambda { |platform| where(:build_for_platform_id => platform) }
@ -135,7 +136,7 @@ class BuildList < ActiveRecord::Base
serialize :extra_repositories, Array
serialize :extra_build_lists, Array
after_commit :place_build
after_commit :place_build, :on => :create
after_destroy :remove_container
state_machine :status, :initial => :waiting_for_response do
@ -155,6 +156,7 @@ class BuildList < ActiveRecord::Base
end
end
after_transition :on => :place_build, :do => :add_to_queue
after_transition :on => :published,
:do => [:set_version_and_tag, :actualize_packages]
after_transition :on => :publish, :do => :set_publisher
@ -165,18 +167,11 @@ class BuildList < ActiveRecord::Base
:unless => lambda { |build_list| build_list.auto_publish? }
event :place_build do
transition :waiting_for_response => :build_pending, :if => lambda { |build_list|
build_list.add_to_queue == BuildList::SUCCESS
}
%w[BUILD_PENDING PROJECT_VERSION_NOT_FOUND].each do |code|
transition :waiting_for_response => code.downcase.to_sym, :if => lambda { |build_list|
build_list.add_to_queue == BuildList.const_get(code)
}
end
transition :waiting_for_response => :build_pending
end
event :start_build do
transition [ :build_pending, :project_version_not_found ] => :build_started
transition :build_pending => :build_started
end
event :cancel do
@ -295,12 +290,8 @@ class BuildList < ActiveRecord::Base
end
def add_to_queue
# TODO: Investigate: why 2 tasks will be created without checking @state
unless @status
add_job_to_abf_worker_queue
update_column(:bs_id, id)
end
@status ||= BUILD_PENDING
add_job_to_abf_worker_queue
update_column(:bs_id, id)
end
def self.human_status(status)
@ -420,14 +411,6 @@ class BuildList < ActiveRecord::Base
path << "#{bl.id}/#{bl.arch.name}/#{bl.save_to_repository.name}/release"
include_repos_hash["container_#{bl.id}"] = path
end
if save_to_platform.personal? && use_save_to_repository
include_repos_hash["#{save_to_platform.name}_release"] = save_to_platform.
public_downloads_url(
build_for_platform.name,
arch.name,
save_to_repository.name
) + 'release'
end
git_project_address = project.git_project_address user
# git_project_address.gsub!(/^http:\/\/(0\.0\.0\.0|localhost)\:[\d]+/, 'https://abf.rosalinux.ru') unless Rails.env.production?
@ -469,10 +452,6 @@ class BuildList < ActiveRecord::Base
end
end
def use_save_to_repository_for_main_platforms
self.use_save_to_repository = true if save_to_platform.main?
end
def set_publisher
self.publisher ||= user
save
@ -493,9 +472,8 @@ class BuildList < ActiveRecord::Base
end
def prepare_extra_build_lists
bls = BuildList.where(:id => extra_build_lists).published_container.accessible_by(current_ability, :read)
if save_to_platform && save_to_platform.main?
bls = bls.where(:save_to_platform_id => save_to_platform.id)
bls = BuildList.for_extra_build_lists(extra_build_lists, current_ability, save_to_platform)
if save_to_platform
if save_to_platform.distrib_type == 'rhel'
bls = bls.where('
(build_lists.arch_id = ? AND projects.publish_i686_into_x86_64 is not true) OR
@ -504,7 +482,6 @@ class BuildList < ActiveRecord::Base
else
bls = bls.where(:arch_id => arch_id)
end
end
self.extra_build_lists = bls.pluck('build_lists.id')
end

View File

@ -1,20 +1,25 @@
class MassBuild < ActiveRecord::Base
belongs_to :platform
belongs_to :build_for_platform, :class_name => 'Platform', :conditions => {:platform_type => 'main'}
belongs_to :save_to_platform, :class_name => 'Platform'
belongs_to :user
has_many :build_lists, :dependent => :destroy
serialize :extra_repositories, Array
serialize :extra_build_lists, Array
scope :recent, order("#{table_name}.created_at DESC")
scope :by_platform, lambda { |platform| where(:platform_id => platform.id) }
scope :by_platform, lambda { |platform| where(:save_to_platform_id => platform.id) }
scope :outdated, where("#{table_name}.created_at < ?", Time.now + 1.day - BuildList::MAX_LIVE_TIME)
attr_accessor :arches
attr_accessible :arches, :auto_publish, :projects_list
attr_accessible :arches, :auto_publish, :projects_list, :build_for_platform_id,
:extra_repositories, :extra_build_lists
validates :platform_id, :arch_names, :name, :user_id, :projects_list, :presence => true
validates :save_to_platform_id, :build_for_platform_id, :arch_names, :name, :user_id, :projects_list, :presence => true
validates_inclusion_of :auto_publish, :in => [true, false]
after_create :build_all
before_validation :set_data
after_commit :build_all, :on => :create
before_validation :set_data, :on => :create
COUNT_STATUSES = [
:build_lists,
@ -36,12 +41,12 @@ class MassBuild < ActiveRecord::Base
next if name.blank?
name.chomp!; name.strip!
if project = Project.joins(:repositories).where('repositories.id in (?)', platform.repository_ids).find_by_name(name)
if project = Project.joins(:repositories).where('repositories.id in (?)', save_to_platform.repository_ids).find_by_name(name)
begin
return if self.reload.stop_build
arches_list.each do |arch|
rep = (project.repositories & platform.repositories).first
project.build_for(platform, rep.id, user, arch, auto_publish, self.id, 0)
rep_id = (project.repository_ids & save_to_platform.repository_ids).first
project.build_for(build_for_platform, save_to_platform, rep_id, user, arch, auto_publish, self, 0)
end
rescue RuntimeError, Exception
end
@ -99,9 +104,8 @@ class MassBuild < ActiveRecord::Base
end
def set_data
if new_record?
self.name = "#{Time.now.utc.to_date.strftime("%d.%b")}-#{platform.name}"
self.arch_names = Arch.where(:id => self.arches).map(&:name).join(", ")
end
self.name = "#{Time.now.utc.to_date.strftime("%d.%b")}-#{save_to_platform.name}"
self.arch_names = Arch.where(:id => self.arches).map(&:name).join(", ")
self.build_for_platform = save_to_platform if save_to_platform && save_to_platform.main?
end
end

View File

@ -16,7 +16,7 @@ class Platform < ActiveRecord::Base
has_many :packages, :class_name => "BuildList::Package", :dependent => :destroy
has_many :mass_builds
has_many :mass_builds, :foreign_key => :save_to_platform_id
validates :description, :presence => true
validates :visibility, :presence => true, :inclusion => {:in => VISIBILITIES}

View File

@ -146,27 +146,35 @@ class Project < ActiveRecord::Base
#path #share by NFS
end
def build_for(platform, repository_id, user, arch = Arch.find_by_name('i586'), auto_publish = false, mass_build_id = nil, priority = 0)
def build_for(build_for_platform, save_to_platform, repository_id, user, arch = Arch.find_by_name('i586'), auto_publish = false, mass_build = nil, priority = 0)
# Select main and project platform repository(contrib, non-free and etc)
# If main does not exist, will connect only project platform repository
# If project platform repository is main, only main will be connect
main_rep_id = platform.repositories.find_by_name('main').try(:id)
build_reps_ids = [main_rep_id, repository_id].compact.uniq
main_rep_id = build_for_platform.repositories.find_by_name('main').try(:id)
include_repos = ([main_rep_id] << (save_to_platform.main? ? repository_id : nil)).compact.uniq
project_version = repo.commits("#{platform.name}").try(:first).try(:id) ?
platform.name : 'master'
project_version = if repo.commits("#{save_to_platform.name}").try(:first).try(:id)
save_to_platform.name
elsif repo.commits("#{build_for_platform.name}").try(:first).try(:id)
build_for_platform.name
else
default_branch
end
build_list = build_lists.build do |bl|
bl.save_to_platform = platform
bl.build_for_platform = platform
bl.update_type = 'newpackage'
bl.arch = arch
bl.project_version = project_version
bl.user = user
bl.auto_publish = auto_publish
bl.include_repos = build_reps_ids
bl.priority = priority
bl.mass_build_id = mass_build_id
bl.save_to_repository_id = repository_id
bl.save_to_platform = save_to_platform
bl.build_for_platform = build_for_platform
bl.update_type = 'newpackage'
bl.arch = arch
bl.project_version = project_version
bl.user = user
bl.auto_publish = auto_publish
bl.include_repos = include_repos
bl.extra_repositories = mass_build.extra_repositories
bl.extra_build_lists = mass_build.extra_build_lists
bl.priority = priority
bl.mass_build_id = mass_build.id
bl.save_to_repository_id = repository_id
end
build_list.save
end

View File

@ -1,7 +1,7 @@
json.build_list do |json|
json.(@build_list, :id, :container_status, :status, :duration)
json.(@build_list, :update_type, :priority, :new_core)
json.(@build_list, :advisory, :mass_build, :use_save_to_repository)
json.(@build_list, :advisory, :mass_build)
json.(@build_list, :auto_publish, :package_version, :commit_hash, :last_published_commit_hash, :auto_create_container)
json.build_log_url log_build_list_path(@build_list)
@ -56,7 +56,7 @@ json.build_list do |json|
end
extra_repos = Repository.includes(:platform).where(:id => @build_list.extra_repositories)
json.extra_repos extra_repos do |json_extra_repos, repo|
json.extra_repositories extra_repos do |json_extra_repos, repo|
json.partial! 'repositories',
:repository => repo,
:json => json_extra_repos

View File

@ -13,8 +13,7 @@
- if can? :show, @platform
%li{:class => (act == :index && contr == :maintainers) ? 'active' : nil}
= link_to t("layout.platforms.maintainers"), platform_maintainers_path(@platform)
- if @platform.main? && can?(:show, @platform)
%li{:class => (contr == :mass_builds && [:index, :create].include?(act)) ? 'active' : ''}
%li{:class => (contr == :mass_builds) ? 'active' : ''}
= link_to t("layout.platforms.mass_build"), platform_mass_builds_path(@platform)
- if can? :read, @platform.products.build
%li{:class => (contr == :products) ? 'active' : ''}

View File

@ -1,17 +0,0 @@
= form_for :build, :url => platform_mass_builds_path(@platform), :html => { :class => 'form mass_build', :method => :post } do |f|
%section.left
=render 'repos_or_list_choice'
%br
= f.submit t("layout.projects.build_button")
%section.right
%h3= t("activerecord.attributes.build_list.arch")
- Arch.recent.each do |arch|
.lefter
= check_box_tag "arches[]", arch.id, (params[:arches]||[]).include?(arch.id.to_s), :id => "arches_#{arch.id}"
= label_tag "arches_#{arch.id}", arch.name
.both
%h3= t("activerecord.attributes.build_list.preferences")
.both.bottom_20
= check_box_tag :auto_publish, true, @auto_publish_selected, :id => 'auto_publish'
= label_tag :auto_publish, t('activerecord.attributes.build_list.auto_publish')
.both

View File

@ -1,8 +0,0 @@
%h3=t("layout.mass_builds.repositories")
-@platform.repositories.each do |rep|
.both
=check_box_tag "repositories[]", rep.id, (params[:repositories]||[]).include?(rep.id.to_s), :id => "repositories_#{rep.id}", :href => "#{projects_list_platform_repository_path(@platform, rep)}?text=true"
=label_tag "repositories_#{rep.id}", rep.name
%h3=t("layout.mass_builds.projects_list")
=text_area_tag :projects_list, nil

View File

@ -1,7 +1,7 @@
= render 'platforms/base/submenu'
= render 'platforms/base/sidebar'
= render 'form' if can? :create, @platform.mass_builds.new
= link_to t('layout.mass_builds.new'), new_platform_mass_build_path(@platform), :class => 'button' if can? :create, @platform.mass_builds.build
%table.tablesorter.unbordered{:cellpadding => "0", :cellspacing => "0"}
%thead

View File

@ -0,0 +1,44 @@
- set_meta_tags :title => [title_object(@platform), t('layout.mass_builds.new')]
= render 'platforms/base/submenu'
= render 'platforms/base/sidebar'
= form_for [@platform, @mass_build], :html => { :class => 'form mass_build', :method => :post } do |f|
%section.left
%h3=t('layout.mass_builds.repositories')
- @platform.repositories.each do |rep|
.both
= check_box_tag "repositories[]", rep.id, (params[:repositories]||[]).include?(rep.id.to_s), :id => "repositories_#{rep.id}", :href => "#{projects_list_platform_repository_path(@platform, rep)}?text=true"
= label_tag "repositories_#{rep.id}", rep.name
%h3=t('layout.mass_builds.projects_list')
= f.text_area :projects_list
%br
= f.submit t("layout.projects.build_button")
%section.right
%h3= t("activerecord.attributes.build_list.arch")
- Arch.recent.each do |arch|
.lefter
= check_box_tag "arches[]", arch.id, (params[:arches]||[]).include?(arch.id.to_s), :id => "arches_#{arch.id}"
= label_tag "arches_#{arch.id}", arch.name
.both
- if @platform.personal?
%h3= t('activerecord.attributes.build_list.build_for_platform')
= f.collection_select :build_for_platform_id, Platform.main, :id, :name
.both
= render 'shared/autocomplete_form',
:field => :extra_repositories,
:field_class => Repository,
:placeholder => 'uxteam_personal',
:subject => @mass_build,
:autocomplete_path => autocomplete_extra_repositories_autocompletes_path
= render 'shared/autocomplete_form',
:field => :extra_build_lists,
:field_class => BuildList,
:placeholder => '1000000',
:subject => @mass_build,
:autocomplete_path => autocomplete_extra_build_list_autocompletes_path
%h3= t("activerecord.attributes.build_list.preferences")
.both
= f.check_box :auto_publish
= f.label :auto_publish
.both

View File

@ -1,9 +0,0 @@
%tr
- if extra.is_a?(BuildList)
%td= link_to "#{extra.id} (#{extra.project.name} - #{extra.arch.name})", extra
- else
%td= link_to "#{extra.platform.name}/#{extra.name}", [extra.platform, extra]
%td.actions
- field = extra.is_a?(BuildList) ? 'extra_build_lists' : 'extra_repositories'
= hidden_field_tag "build_list[#{field}][]", extra.id
%span.delete &nbsp;

View File

@ -6,8 +6,6 @@
- Platform.main.each do |pl|
- if pl.repository_ids.size > 0
.both
=# check_box_tag "build_for_platforms[]", pl.id, (params[:build_for_platforms]||[]).include?(pl.id.to_s), :class => 'build_bpl_ids', :id => "bpls_#{pl.id}"
=# label_tag "bpls_#{pl.id}", pl.name
%div{:id => "build_for_pl_#{pl.id}", :class => 'build_for_pl'}= pl.name
.offset25= render 'include_repos', :platform => pl
%section.right
@ -23,39 +21,27 @@
%h3= t("activerecord.attributes.build_list.update_type")
.lineForm= f.select :update_type, BuildList::UPDATE_TYPES
#extra-repos-and-build-lists
%h3= t("activerecord.attributes.build_list.extra_repos")
%span.icon-question-sign
%div#extra-repos-and-build-lists-dialog{:title => t("activerecord.attributes.build_list.extra_repos")}
%b= t('helpers.extra_repos_and_build_lists.header')
%br
%br
%b= t('helpers.extra_repos_and_build_lists.build_lists.header')
- (1..4).each do |index|
%p= t("helpers.extra_repos_and_build_lists.build_lists.message#{index}").html_safe
%br
%b= t('helpers.extra_repos_and_build_lists.repos.header')
%p= t('helpers.extra_repos_and_build_lists.repos.message1')
%br
%b= t('helpers.extra_repos_and_build_lists.repos.header2')
%p= t('helpers.extra_repos_and_build_lists.repos.message2')
%p= t('helpers.extra_repos_and_build_lists.repos.message3').html_safe
= autocomplete_field_tag 'extra_repos', nil, autocomplete_to_extra_repos_and_builds_build_lists_path, :id_element => '#extra_repo_field'
= hidden_field_tag 'extra_repo', nil, :id => 'extra_repo_field'
= submit_tag t("layout.add"), :class => 'button', :id => 'add'
%table.tablesorter{:cellpadding => "0", :cellspacing => "0"}
%tbody
= render :partial => 'extra', :collection => Repository.where(id: @build_list.extra_repositories)
= render :partial => 'extra', :collection => BuildList.where(id: @build_list.extra_build_lists)
= render 'shared/autocomplete_form',
:field => :extra_repositories,
:field_class => Repository,
:placeholder => 'uxteam_personal',
:subject => @build_list,
:autocomplete_path => autocomplete_extra_repositories_autocompletes_path,
:default_values => @project.repositories.select{ |r| r.platform.personal? }
= render 'shared/autocomplete_form',
:field => :extra_build_lists,
:field_class => BuildList,
:placeholder => '1000000',
:subject => @build_list,
:autocomplete_path => autocomplete_extra_build_list_autocompletes_path
%h3= t("activerecord.attributes.build_list.preferences")
- [:auto_publish, :auto_create_container, :use_save_to_repository].each do |kind|
- [:auto_publish, :auto_create_container].each do |kind|
.both
= f.check_box kind
= f.label kind
%br
= f.submit t("layout.projects.build_button")
.both
%br
= render 'projects/base/submenu'

View File

@ -38,9 +38,6 @@
.rightlist
= link_to "#{@build_list.save_to_platform.name}/#{@build_list.save_to_repository.name}", [@build_list.save_to_platform, @build_list.save_to_repository]
.both
.leftlist= t("activerecord.attributes.build_list.use_save_to_repository")
.rightlist= t("layout.#{@build_list.use_save_to_repository?}_")
.both
.leftlist= t("activerecord.attributes.build_list.include_repos")
.rightlist= (@build_list.include_repos||[]).map{|r| Repository.find(r).name}.join(', ')
.both

View File

@ -0,0 +1,43 @@
-#
Variables:
subject
field
field_class
autocomplete_path
placeholder
default_values (optional)
- default_values ||= []
- subject_class = subject.class.name.underscore
.autocomplete-form{:subject_class => subject_class, :field => field, :path => autocomplete_path, :class => field}
%h3= t("activerecord.attributes.build_list.#{field}")
%span.icon-question-sign
.dialog{:title => t("activerecord.attributes.build_list.#{field}"), :id => "#{field}_dialog"}
= render "shared/autocomplete_docs/#{field}"
.both
= autocomplete_field_tag field, nil, "#{autocomplete_path}?#{{:platform_id => subject.save_to_platform.try(:id)}.to_param}", :placeholder => placeholder, :class => 'autocomplete', :update_elements => {:id => "##{field}_field", :path => "##{field}_field_path", :label => "##{field}_field_label"}
= hidden_field_tag field, nil, :id => "#{field}_field"
= hidden_field_tag field, nil, :id => "#{field}_field_path"
= hidden_field_tag field, nil, :id => "#{field}_field_label"
= submit_tag t('layout.add'), :class => 'button add'
%table.tablesorter{:cellpadding => "0", :cellspacing => "0"}
%tbody
- field_name = "#{subject_class}[#{field}][]"
- field_class.where(:id => subject.send(field)).each do |extra|
%tr
- if extra.is_a?(BuildList)
%td= link_to "#{extra.id} (#{extra.project.name} - #{extra.arch.name})", extra
- else
%td= link_to "#{extra.platform.name}/#{extra.name}", [extra.platform, extra]
%td.actions
- field = extra.is_a?(BuildList) ? 'extra_build_lists' : 'extra_repositories'
= hidden_field_tag field_name, extra.id
%span.delete &nbsp;
.default-values
- field_class.where(:id => default_values).each do |extra|
.hidden{:label => "#{extra.platform.name}/#{extra.name}",
:path => url_for([extra.platform, extra]),
:name => field_name, :value => extra.id}

View File

@ -0,0 +1,12 @@
:markdown
__Ability to attach at assembly packages of build lists as additional sources of packages.__
<br/>
Requirements for attaching build lists:
- only build list with container can be connected;
- for main platform You can connect only build lists which destined for same platform;
- only build lists with the same architecture will be connected or oriented to the both architectures (the property Publish i686 packages into x86_64 repository (only for rhel) in the settings of project is true).
_Example: only build lists with x86_64 architecture will be connected to x86_64._

View File

@ -0,0 +1,12 @@
:markdown
__Возможность подключить для сборки пакеты из сборочных заданий как дополнительные источники пакетов.__
<br/>
Требования для подключаемых сборочных заданий:
- можно подключить только задание с контейнером;
- для основных платформ возможно подключить только задания, которые предназначены для этой же платформы;
- будут подключены только задания с архитектурой, соотвествующей создаваемой, или предназначенные для обеих архитектур (если установлено соответствующее свойство в настройках rhel-проекта).
ример: для x86_64 архитектуры будут подключены только сборочные задания, собранные для x86_64._

View File

@ -0,0 +1,14 @@
:markdown
__Ability to attach at assembly repositories of platforms as additional sources of packages.__
<br/>
Requirements for attaching repositories:
- attaching repositories from other platform available only for build list into the personal platform.
How to attach a repository:
- write the name of platform, choose repository from the list for attaching and click to "Add" button.
_Example: correct input "uxteam_personal", wrong - "uxteam_personal/main"._

View File

@ -0,0 +1,14 @@
:markdown
__Возможность подключить для сборки репозитории платформ как дополнительные источники пакетов.__
<br/>
Требования для репозиториев:
- использовать репозитории из других персональных платформ возможно только для сборки в персональную платформу.
Как подключить репозиторий:
- добавьте имя платформы, затем из списка выберете репозиторий для поключения и нажмите кнопку "Добавить".
ример: правильно ввести "uxteam_personal", неправильно: "uxteam_personal/main"._

View File

@ -9,12 +9,13 @@ Mime::Type.register "text/plain", 'diff'
Mime::Type.register "text/plain", 'patch'
# add rpm spec as mime type for *.spec files
[["text/x-python", ['py'], '8bit'],
["text/x-rpm-spec", ['spec'], '8bit'],
["text/x-csrc", ['h', 'c'], '8bit'],
["text/x-c++src", ['cpp'], '8bit'],
["text/x-diff", ['diff'], '8bit'],
["text/x-markdown", ['md'], '8bit']
[["text/x-python", ['py'], '8bit'],
["text/x-rpm-spec", ['spec'], '8bit'],
["application/x-csrc", ['h', 'c'], '8bit'],
["application/x-c++src", ['cpp', 'cc'], '8bit'],
["application/x-csharp", ['cs'], '8bit'],
["text/x-diff", ['diff'], '8bit'],
["text/x-markdown", ['md'], '8bit']
].each do |type|
MIME::Types.add MIME::Type.from_array(type)
end

View File

@ -7,7 +7,8 @@ en:
build_list:
bs_id: Id
name: Name
extra_repos: Extra repositories and build lists
extra_repositories: Extra repositories
extra_build_lists: Extra build lists
auto_create_container: Create container automatically
container_path: Container path
status: Status
@ -23,10 +24,9 @@ en:
include_repos: Included repositories
created_at: Created on
save_to_repository: Save to repository
use_save_to_repository: Use 'save to repository' for assembly
build_for_platform: Build for platform
update_type: Update type
auto_publish: Automated publising
auto_publish: Automated publishing
project_version: Version
user: User
publisher: Publisher
@ -134,7 +134,6 @@ en:
success: Build complete
build_started: Build started
platform_pending: Platform pending
project_version_not_found: Project version not found
log:
build_log: Build Log
@ -154,21 +153,6 @@ en:
show_filter: Show filters
hide_filter: Hide filters
helpers:
extra_repos_and_build_lists:
header: 'Ability to attach at assembly additional sources of packages: repositories of platforms and packages of build lists.'
build_lists:
header: 'Requirements for attaching build lists:'
message1: '- only build list with container can be connected;'
message2: '- for main platform You can connect only build lists which destined for same platform;'
message3: '- only build lists with the same architecture will be connected or oriented to the both architectures (the property Publish i686 packages into x86_64 repository (only for rhel) in the settings of project is true).'
message4: '<i>Example: only build lists with x86_64 architecture will be connected to x86_64</i>'
repos:
header: 'Requirements for attaching repositories:'
message1: '- attaching repositories from other platform available only for build list into the personal platform.'
header2: 'How to attach a repository:'
message2: '- write the name of platform, choose repository from the list for attaching and click to "Add" button.'
message3: '<i>Example: correct input "uxteam_personal", wrong - "uxteam_personal/main".</i>'
flash:
build_list:
saved: Build list for project version '%{project_version}', platform '%{build_for_platform}' and architecture '%{arch}' has been created successfully

View File

@ -7,7 +7,8 @@ ru:
build_list:
bs_id: Id
name: Название
extra_repos: Дополнительные репозитории и сборки
extra_repositories: Дополнительные репозитории
extra_build_lists: Дополнительные сборки
auto_create_container: Создать контейнер автоматически
container_path: Путь до контейнера
status: Статус
@ -23,7 +24,6 @@ ru:
include_repos: Подключаемые репозитории
created_at: Создан
save_to_repository: Сохранить в репозиторий
use_save_to_repository: Использовать 'cохранить в репозиторий' для сборки
build_for_platform: Собрано для платформы
update_type: Критичность обновления
auto_publish: Автоматическая публикация
@ -133,7 +133,6 @@ ru:
success: собран
build_started: собирается
platform_pending: платформа в процессе создания
project_version_not_found: версия не найдена
log:
build_log: Лог сборки
@ -153,21 +152,6 @@ ru:
show_filter: Показать фильтры
hide_filter: Скрыть фильтры
helpers:
extra_repos_and_build_lists:
header: 'Возможность подключить для сборки дополнительные источники пакетов: репозитории из платформ и пакеты из сборочных заданий.'
build_lists:
header: 'Требования для подключемых сборочных заданий:'
message1: '- только задание с контейнером может быть подключен;'
message2: '- для основных платформ возможно подключить только задания, которые предназначены для этой же платформы;'
message3: '- будут подключены только задания с архитектурой, соотвествующей создаваемой, или предназначененные для обеих архитектур (установлено свойство Публиковать i686 пакеты в x86_64 репозиторий (только для rhel) в настройках проекта).'
message4: '<i>Пример: для x86_64 архитектуры будут подключены только сборочные задания, собранные для x86_64</i>'
repos:
header: 'Требования для репозиториев:'
message1: '- использовать репозитории из других платформ возможно только для сборки в персональную платформу.'
header2: 'Как подключить репозиторий:'
message2: '- добавьте имя платформы, затем из списка выберете репозиторий для поключения и нажмите кнопку "Добавить".'
message3: '<i>Пример: правильно ввести "uxteam_personal", неправильно: "uxteam_personal/main".</i>'
flash:
build_list:
saved: Билд лист для версии '%{project_version}', платформы '%{build_for_platform}' и архитектуры '%{arch}' создан успешно

View File

@ -1,6 +1,7 @@
en:
layout:
mass_builds:
new: New mass build
publish_success: Publish success builds
publish_test_failed: Publish test failed builds
repositories: Repositories
@ -22,6 +23,6 @@ en:
updated_at: Updated
arch_names: Architectures
user: User
auto_publish: Auto Publish
auto_publish: Automated publishing
repositories: Repositories
projects_list: Projects list

View File

@ -1,6 +1,7 @@
ru:
layout:
mass_builds:
new: Новая массовая сборка
publish_success: Опубликовать успешные сборки
publish_test_failed: Опубликовать сборки с проваленными тестами
repositories: Репозитории
@ -22,6 +23,6 @@ ru:
updated_at: Обновлен
arch_names: Архитектуры
user: Пользователь
auto_publish: Авто Публикация
auto_publish: Автоматическая публикация
repositories: Репозитории
projects_list: Список проектов

View File

@ -101,7 +101,7 @@ en:
updated_at: Updated on
has_issues: Issues tracker enabled
has_wiki: Wiki enabled
srpm: Import code from src.rpm
srpm: Import code from src.rpm (optional)
who_owns:
me: Myself
group: Group

View File

@ -101,7 +101,7 @@ ru:
updated_at: Обновлен
has_issues: Включить трэкер
has_wiki: Включить Wiki
srpm: Импортировать код из src.rpm
srpm: Импортировать код из src.rpm (опционально)
who_owns:
me: Я
group: Группа

View File

@ -149,7 +149,7 @@ Rosa::Application.routes.draw do
get :advisories
end
resources :mass_builds, :only => [:create, :index] do
resources :mass_builds, :only => [:create, :new, :index] do
member do
post :cancel
post :publish
@ -189,6 +189,8 @@ Rosa::Application.routes.draw do
collection do
get :autocomplete_user_uname
get :autocomplete_group_uname
get :autocomplete_extra_build_list
get :autocomplete_extra_repositories
end
end
@ -237,8 +239,6 @@ Rosa::Application.routes.draw do
get :log
end
collection {
get :autocomplete_to_extra_repos_and_builds
get :update_extra_repos_and_builds
post :search
}
end

View File

@ -0,0 +1,9 @@
class DropUseSaveToRepositoryFromBuildLists < ActiveRecord::Migration
def up
remove_column :build_lists, :use_save_to_repository
end
def down
add_column :build_lists, :use_save_to_repository, :boolean, :default => true
end
end

View File

@ -0,0 +1,22 @@
class AddExtraReposAndBuildListsToMassBuild < ActiveRecord::Migration
class MassBuild < ActiveRecord::Base
end
def up
add_column :mass_builds, :save_to_platform_id, :integer
MassBuild.update_all('save_to_platform_id = platform_id')
change_column :mass_builds, :save_to_platform_id, :integer, :null => false
change_column :mass_builds, :platform_id, :integer, :null => false
rename_column :mass_builds, :platform_id, :build_for_platform_id
add_column :mass_builds, :extra_repositories, :text
add_column :mass_builds, :extra_build_lists, :text
end
def down
remove_column :mass_builds, :extra_repositories
remove_column :mass_builds, :extra_build_lists
remove_column :mass_builds, :save_to_platform_id
rename_column :mass_builds, :build_for_platform_id, :platform_id
end
end

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20130417162427) do
ActiveRecord::Schema.define(:version => 20130603124853) do
create_table "activity_feeds", :force => true do |t|
t.integer "user_id", :null => false
@ -133,7 +133,6 @@ ActiveRecord::Schema.define(:version => 20130417162427) do
t.boolean "new_core", :default => true
t.string "last_published_commit_hash"
t.integer "container_status"
t.boolean "use_save_to_repository", :default => true
t.boolean "auto_create_container", :default => false
t.text "extra_repositories"
t.text "extra_build_lists"
@ -272,7 +271,7 @@ ActiveRecord::Schema.define(:version => 20130417162427) do
add_index "labels", ["project_id"], :name => "index_labels_on_project_id"
create_table "mass_builds", :force => true do |t|
t.integer "platform_id"
t.integer "build_for_platform_id", :null => false
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
@ -292,6 +291,9 @@ ActiveRecord::Schema.define(:version => 20130417162427) do
t.boolean "new_core", :default => true
t.integer "success_count", :default => 0, :null => false
t.integer "build_canceled_count", :default => 0, :null => false
t.integer "save_to_platform_id", :null => false
t.text "extra_repositories"
t.text "extra_build_lists"
end
create_table "platforms", :force => true do |t|

View File

@ -73,6 +73,12 @@ module AbfWorker
redis.lrem LOCKED_REP_AND_PLATFORMS, 0, lock_str
end
def packages_structure
structure = {:sources => [], :binaries => {}}
Arch.pluck(:name).each{ |name| structure[:binaries][name.to_sym] = [] }
structure
end
def redis
Resque.redis
end
@ -81,7 +87,7 @@ module AbfWorker
platform_path = "#{build_list.save_to_platform.path}/container/#{build_list.id}"
system "rm -rf #{platform_path} && mkdir -p #{platform_path}"
packages = {:sources => [], :binaries => {:x86_64 => [], :i586 => []}}
packages = packages_structure
packages[:sources] = build_list.packages.by_package_type('source').pluck(:sha1).compact
packages[:binaries][build_list.arch.name.to_sym] = build_list.packages.by_package_type('binary').pluck(:sha1).compact
@ -109,7 +115,7 @@ module AbfWorker
:type => :publish,
:time_living => 9600, # 160 min
:packages => packages,
:old_packages => {:sources => [], :binaries => {:x86_64 => [], :i586 => []}},
:old_packages => packages_structure,
:build_list_ids => [build_list.id],
:projects_for_cleanup => [],
:extra => {:create_container => true}
@ -129,7 +135,7 @@ module AbfWorker
build_lists_for_cleanup << bl if bl
end
old_packages = {:sources => [], :binaries => {:x86_64 => [], :i586 => []}}
old_packages = packages_structure
build_lists_for_cleanup.each do |bl|
bl.last_published.includes(:packages).limit(2).each{ |old_bl|
fill_packages(old_bl, old_packages, :fullname)
@ -248,7 +254,7 @@ module AbfWorker
build_lists = build_lists.where('build_lists.id NOT IN (?)', locked_ids) unless locked_ids.empty?
build_lists = build_lists.limit(150)
old_packages = {:sources => [], :binaries => {:x86_64 => [], :i586 => []}}
old_packages = self.class.packages_structure
projects_for_cleanup.each do |key|
@redis.lrem PROJECTS_FOR_CLEANUP, 0, key
@ -256,8 +262,8 @@ module AbfWorker
next unless packages
packages = JSON.parse packages
old_packages[:sources] |= packages['sources']
[:x86_64, :i586].each do |arch|
old_packages[:binaries][arch] |= packages['binaries'][arch.to_s]
Arch.pluck(:name).each do |arch|
old_packages[:binaries][arch.to_sym] |= packages['binaries'][arch]
end
end
@ -295,10 +301,7 @@ module AbfWorker
:extra => {:lock_str => lock_str}
}
packages = {:sources => [], :binaries => {:x86_64 => [], :i586 => []}}
build_list_ids = []
new_sources = {}
packages, build_list_ids, new_sources = self.class.packages_structure, [], {}
build_lists.each do |bl|
# remove duplicates of sources for different arches
bl.packages.by_package_type('source').each{ |s| new_sources["#{s.fullname}"] = s.sha1 }

View File

@ -24,15 +24,13 @@ class String
# same as reverse.truncate.reverse
def rtruncate(length, options = {})
text = self.dup
chars = self.dup.mb_chars
return self if chars.length <= length
options[:omission] ||= "..."
options[:separator] ||= '/'
length_with_room_for_omission = length - options[:omission].mb_chars.length
chars = text.mb_chars
stop = options[:separator] ?
(chars.index(options[:separator].mb_chars, length_with_room_for_omission) || length_with_room_for_omission) : length_with_room_for_omission
(chars.length > length ? "#{options[:omission]}#{chars[-(stop+1)...-1]}" : text).to_s
start = chars.length - length + options[:omission].mb_chars.length
stop = options[:separator] ? (chars.index(options[:separator].mb_chars, start) || start) : start
"#{options[:omission]}#{chars[stop..-1]}".to_s
end
end

View File

@ -1,25 +0,0 @@
require 'highline/import'
require 'open-uri'
namespace :build do
desc "Build projects from list"
task :projects => :environment do
source = ENV['SOURCE'] || 'http://dl.dropbox.com/u/984976/rebuild_list.txt'
owner = User.find_by_uname!(ENV['OWNER'] || 'warpc')
platform = Platform.find_by_name!(ENV['PLATFORM'] || 'rosa2012lts')
arch = Arch.find_by_name!(ENV['ARCH'] || 'i586')
say "START build projects from #{source} for platform=#{platform.name}, owner=#{owner.uname}, arch=#{arch.name}"
open(source).readlines.each do |name|
name.chomp!; name.strip! #; name.downcase!
if p = Project.joins(:repositories).where('repositories.id IN (?)', platform.repositories).find_by_name(name)
# Old code p.build_for(platform, owner, arch)
say "== Build #{p.name} =="
else
say "== Not found #{name} =="
end
sleep 0.2
end
say 'DONE'
end
end

View File

@ -152,14 +152,14 @@ describe Api::V1::BuildListsController do
context "if it has another status" do
before do
@build_list.update_column(:status, BuildList::PROJECT_VERSION_NOT_FOUND)
@build_list.update_column(:status, BuildList::SUCCESS)
do_cancel
end
it_should_behave_like 'validation error via build list api', I18n.t('layout.build_lists.cancel_fail')
it "should not change status of build list" do
@build_list.reload.status.should == BuildList::PROJECT_VERSION_NOT_FOUND
@build_list.reload.status.should == BuildList::SUCCESS
end
end
end
@ -288,7 +288,7 @@ describe Api::V1::BuildListsController do
context "if it has another status" do
before(:each) do
@build_list.update_column(:status, BuildList::PROJECT_VERSION_NOT_FOUND)
@build_list.update_column(:status, BuildList::BUILD_CANCELED)
do_publish
end
@ -297,7 +297,7 @@ describe Api::V1::BuildListsController do
end
it "should not change status of build list" do
@build_list.reload.status.should == BuildList::PROJECT_VERSION_NOT_FOUND
@build_list.reload.status.should == BuildList::BUILD_CANCELED
end
end
@ -388,14 +388,14 @@ describe Api::V1::BuildListsController do
context "if it has another status" do
before(:each) do
@build_list.update_column(:status, BuildList::BUILD_ERROR)
@build_list.update_column(:status, BuildList::BUILD_CANCELED)
do_reject_publish
end
it_should_behave_like 'validation error via build list api', I18n.t('layout.build_lists.reject_publish_fail')
it "should not change status of build list" do
@build_list.reload.status.should == BuildList::BUILD_ERROR
@build_list.reload.status.should == BuildList::BUILD_CANCELED
end
end
end
@ -788,6 +788,5 @@ describe Api::V1::BuildListsController do
end
end
end
end
end

View File

@ -5,8 +5,9 @@ describe AutocompletesController do
before {stub_symlink_methods}
context 'for user' do
let(:user) { FactoryGirl.create(:user) }
before do
set_session_for(FactoryGirl.create(:user))
set_session_for user
end
it 'should be able to perform autocomplete_group_uname action' do
@ -19,6 +20,44 @@ describe AutocompletesController do
response.should be_success
end
context 'autocomplete_extra_build_list' do
let(:build_list) { FactoryGirl.create(:build_list_core, :user => user) }
let(:params) { { :term => build_list.id,
:platform_id => build_list.save_to_platform_id } }
it 'no data when build_list without container' do
get :autocomplete_extra_build_list, params
response.body.should == '[]'
end
it 'shows data when build_list with container' do
build_list.update_column(:container_status, BuildList::BUILD_PUBLISHED)
get :autocomplete_extra_build_list, params
response.body.should_not == '[]'
end
end
context 'autocomplete_extra_repositories' do
let(:repository) { FactoryGirl.create(:repository) }
let(:params) { { :term => repository.platform.name,
:platform_id => repository.platform_id } }
before do
repository.platform.add_member(user)
end
it 'no data when repository of main platform' do
get :autocomplete_extra_repositories, params
response.body.should == '[]'
end
it 'shows data when repository of personal platform' do
Platform.update_all(:platform_type => 'personal')
get :autocomplete_extra_repositories, params
response.body.should_not == '[]'
end
end
end
context 'for guest' do
@ -27,14 +66,16 @@ describe AutocompletesController do
set_session_for(User.new)
end
it 'should not be able to perform autocomplete_group_uname action' do
get :autocomplete_group_uname
response.should redirect_to(new_user_session_path)
end
it 'should not be able to perform autocomplete_user_uname action' do
get :autocomplete_user_uname
response.should redirect_to(new_user_session_path)
[
:autocomplete_group_uname,
:autocomplete_user_uname,
:autocomplete_extra_build_list,
:autocomplete_extra_repositories
].each do |action|
it "should not be able to perform #{action} action" do
get action
response.should redirect_to(new_user_session_path)
end
end
end

View File

@ -7,6 +7,11 @@ shared_examples_for 'mass_build platform owner' do
response.should render_template(:index)
end
it 'should be able to perform new action' do
get :new, :platform_id => @platform
response.should render_template(:new)
end
it 'should be able to perform create action' do
post :create, @create_params
response.should redirect_to(platform_mass_builds_path(@platform))
@ -46,19 +51,19 @@ shared_examples_for 'mass_build platform owner' do
get :get_list, :platform_id => @platform, :id => @mass_build, :kind => 'failed_builds_list'
response.should be_success
end
end
context 'for personal platform' do
before(:each) do
Platform.update_all(:platform_type => 'personal')
end
[:cancel, :get_list, :create, :publish].each do |action|
it "should not be able to perform #{ action } action" do
get action, :platform_id => @platform, :id => @mass_build.id
response.should redirect_to(forbidden_path)
end
shared_examples_for 'mass_build platform owner of personal platform' do
before(:each) do
Platform.update_all(:platform_type => 'personal')
repository = FactoryGirl.create(:repository)
@mass_build.build_lists.each do |bl|
bl.build_for_platform = repository.platform
bl.include_repos = [repository.id]
bl.save
end
end
it_should_behave_like 'mass_build platform owner'
end
shared_examples_for 'mass_build platform reader' do
@ -72,6 +77,11 @@ shared_examples_for 'mass_build platform reader' do
response.should be_success
end
it "should not be able to perform new action" do
get :new, :platform_id => @platform
response.should redirect_to(forbidden_path)
end
it "should not be able to perform create action" do
get :create, :platform_id => @platform
response.should redirect_to(forbidden_path)
@ -113,13 +123,16 @@ describe Platforms::MassBuildsController do
@repository.projects << project
@create_params = {
:platform_id => @platform,
:projects_list => @repository.projects.map(&:name).join("\n"),
:arches => [Arch.first.id],
:auto_publish => true
:mass_build => {
:projects_list => @repository.projects.map(&:name).join("\n"),
:auto_publish => true,
:build_for_platform_id => @platform
},
:platform_id => @platform,
:arches => [Arch.first.id],
}
@mass_build = FactoryGirl.create(:mass_build, :platform => @platform, :user => @user, :projects_list => project.name)
@mass_build = FactoryGirl.create(:mass_build, :save_to_platform => @platform, :user => @user, :projects_list => project.name)
FactoryGirl.create(:build_list_core, :mass_build => @mass_build, :status => BuildList::SUCCESS)
end
@ -145,12 +158,12 @@ describe Platforms::MassBuildsController do
response.should redirect_to(new_user_session_path)
end
it "should not be able to perform create action" do
get :create, :platform_id => @platform
it "should not be able to perform new action" do
get :new, :platform_id => @platform
response.should redirect_to(new_user_session_path)
end
[:cancel, :publish].each do |action|
[:cancel, :publish, :create].each do |action|
it "should not be able to perform #{action} action" do
post action, :platform_id => @platform, :id => @mass_build
response.should redirect_to(new_user_session_path)
@ -181,6 +194,7 @@ describe Platforms::MassBuildsController do
end
it_should_behave_like 'mass_build platform owner'
it_should_behave_like 'mass_build platform owner of personal platform'
end
context 'for owner user' do
@ -193,6 +207,7 @@ describe Platforms::MassBuildsController do
end
it_should_behave_like 'mass_build platform owner'
it_should_behave_like 'mass_build platform owner of personal platform'
end
context 'for admin user' do
@ -203,6 +218,7 @@ describe Platforms::MassBuildsController do
end
it_should_behave_like 'mass_build platform owner'
it_should_behave_like 'mass_build platform owner of personal platform'
end
context 'for reader user' do

View File

@ -15,34 +15,6 @@ describe Projects::BuildListsController do
end
end
shared_examples_for 'show extra_repos_and_builds actions' do
it 'shows data when perform autocomplete_to_extra_repos_and_builds action' do
@build_list.update_column(:container_status, BuildList::BUILD_PUBLISHED)
get :autocomplete_to_extra_repos_and_builds, {:term => @build_list.id, :platform_id => @build_list.save_to_platform_id}
response.body.should_not == '[]'
end
it 'shows data when perform update_extra_repos_and_builds action' do
@build_list.update_column(:container_status, BuildList::BUILD_PUBLISHED)
get :update_extra_repos_and_builds, {:build_list => {:save_to_repository_id => @build_list.save_to_repository_id, :extra_build_lists => [@build_list.id]}, :extra_repo => ''}
response.body.should_not == ' '
end
end
shared_examples_for 'not show extra_repos_and_builds actions' do
it 'no data when perform autocomplete_to_extra_repos_and_builds action' do
@build_list.update_column(:container_status, BuildList::BUILD_PUBLISHED)
get :autocomplete_to_extra_repos_and_builds, {:term => @build_list.id, :platform_id => @build_list.save_to_platform_id}
response.body.should == '[]'
end
it 'no data when perform update_extra_repos_and_builds action' do
@build_list.update_column(:container_status, BuildList::BUILD_PUBLISHED)
get :update_extra_repos_and_builds, {:build_list => {:save_to_repository_id => @build_list.save_to_repository_id, :extra_build_lists => [@build_list.id]}, :extra_repo => ''}
response.body.should == ' '
end
end
shared_examples_for 'not show build list' do
it 'should not be able to perform show action' do
get :show, @show_params
@ -136,12 +108,6 @@ describe Projects::BuildListsController do
response.should redirect_to(new_user_session_path)
end
[:autocomplete_to_extra_repos_and_builds, :update_extra_repos_and_builds].each do |action|
it "should not be able to perform #{action} action" do
get action
response.should redirect_to(new_user_session_path)
end
end
end
context 'for user' do
@ -287,7 +253,6 @@ describe Projects::BuildListsController do
context 'for open project' do
it_should_behave_like 'show build list'
it_should_behave_like 'not create build list'
it_should_behave_like 'show extra_repos_and_builds actions'
context 'if user is project owner' do
before(:each) {set_session_for(@owner_user)}
@ -311,20 +276,17 @@ describe Projects::BuildListsController do
it_should_behave_like 'not show build list'
it_should_behave_like 'not create build list'
it_should_behave_like 'not show extra_repos_and_builds actions'
context 'if user is project owner' do
before(:each) {set_session_for(@owner_user)}
it_should_behave_like 'show build list'
it_should_behave_like 'create build list'
it_should_behave_like 'show extra_repos_and_builds actions'
end
context 'if user is project read member' do
before(:each) {set_session_for(@member_user)}
it_should_behave_like 'show build list'
it_should_behave_like 'not create build list'
it_should_behave_like 'show extra_repos_and_builds actions'
end
end
end
@ -380,7 +342,6 @@ describe Projects::BuildListsController do
context 'for open project' do
it_should_behave_like 'show build list'
it_should_behave_like 'not create build list'
it_should_behave_like 'show extra_repos_and_builds actions'
context 'if user is group owner' do
before(:each) {set_session_for(@owner_user)}
@ -403,20 +364,17 @@ describe Projects::BuildListsController do
it_should_behave_like 'not show build list'
it_should_behave_like 'not create build list'
it_should_behave_like 'not show extra_repos_and_builds actions'
context 'if user is group owner' do
before(:each) {set_session_for(@owner_user)}
it_should_behave_like 'show build list'
it_should_behave_like 'create build list'
it_should_behave_like 'show extra_repos_and_builds actions'
end
context 'if user is group read member' do
before(:each) {set_session_for(@member_user)}
it_should_behave_like 'show build list'
it_should_behave_like 'not create build list'
it_should_behave_like 'show extra_repos_and_builds actions'
end
end

View File

@ -1,8 +1,7 @@
# -*- encoding : utf-8 -*-
FactoryGirl.define do
factory :mass_build do
association :platform
#name FactoryGirl.generate(:name)
association :save_to_platform
association :user
projects_list "first"
arches { [ Arch.first.id ] }