Permalink
Browse files

Merge pull request #355 from abf/rosa-build:354-add-possibility-to-re…

…build-projects-periodically

 #354: Add possibility to rebuild projects periodically
  • Loading branch information...
2 parents 34a6346 + e1260ea commit 72ee8f4e0cf228cf8ef6b040e2f8d4d84342a26e @alexander-machehin alexander-machehin committed Feb 19, 2014
View
@@ -4,6 +4,7 @@ gem 'rails', '3.2.17'
gem 'redhillonrails_core', git: 'git://github.com/rosa-abf/redhillonrails_core.git', branch: 'rails31' # '~> 2.0.0.pre' # deprecated
gem 'pg', '~> 0.14.0'
+gem 'activerecord-postgres-hstore'
gem 'devise', '~> 2.2.3'
gem 'omniauth'
View
@@ -56,6 +56,10 @@ GEM
activesupport (= 3.2.17)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
+ activerecord-postgres-hstore (0.7.7)
+ activerecord (>= 3.1)
+ pg-hstore (>= 1.1.5)
+ rake
activeresource (3.2.17)
activemodel (= 3.2.17)
activesupport (= 3.2.17)
@@ -272,6 +276,7 @@ GEM
cocaine (~> 0.5.3)
mime-types
pg (0.14.1)
+ pg-hstore (1.2.0)
polyglot (0.3.4)
posix-spawn (0.3.8)
puma (2.7.1)
@@ -459,6 +464,7 @@ PLATFORMS
DEPENDENCIES
RedCloth
+ activerecord-postgres-hstore
airbrake (~> 3.1.2)
ancestry (~> 1.3.0)
angular-i18n (= 0.1.2)
@@ -0,0 +1,34 @@
+RosaABF.controller('ProjectScheduleController', ['$scope', '$http', function($scope, $http) {
+
+ // See: Modules::Models::Autostart::AUTOSTART_STATUSES
+ $scope.statuses = {
+ '0': 'autostart_statuses.0',
+ '1': 'autostart_statuses.1',
+ '2': 'autostart_statuses.2'
+ };
+ $scope.project = null;
+ $scope.owner = null;
+ $scope.items = [];
+
+
+ $scope.init = function(name_with_owner) {
+ var arr = name_with_owner.split('/');
+ $scope.owner = arr[0];
+ $scope.project = arr[1];
+ }
+
+ $scope.updateStatus = function() {
+ $http.put(
+ Routes.project_path($scope.owner, $scope.project),
+ {project: {autostart_status: $scope.autostart_status}, format: 'json'}
+ );
+ }
+
+ $scope.updateSchedule = function(obj) {
+ $http.put(
+ Routes.project_schedule_path($scope.owner, $scope.project),
+ {enabled: obj.enabled, auto_publish: obj.auto_publish, repository_id: obj.repository_id, format: 'json'}
+ );
+ }
+
+}]);
@@ -13,6 +13,9 @@ var _locales = {
],
'platform.automatic_metadata_regeneration.day': 'Раз в день',
'platform.automatic_metadata_regeneration.week': 'Раз в неделю',
+ 'autostart_statuses.0': 'Раз в 12 часов',
+ 'autostart_statuses.1': 'Раз в день',
+ 'autostart_statuses.2': 'Раз в неделю',
<%= BuildList::STATUSES.map{|s| "'build_list.status.#{s}': '#{BuildList.human_status(s)}'"}.join(',') %>
},
<%I18n.locale = :en%>
@@ -27,6 +30,9 @@ var _locales = {
],
'platform.automatic_metadata_regeneration.day': 'Once a day',
'platform.automatic_metadata_regeneration.week': 'Once a week',
+ 'autostart_statuses.0': 'Once a 12 hours',
+ 'autostart_statuses.1': 'Once a day',
+ 'autostart_statuses.2': 'Once a week',
<%= BuildList::STATUSES.map{|s| "'build_list.status.#{s}': '#{BuildList.human_status(s)}'"}.join(',') %>
}
};
@@ -67,14 +67,41 @@ def create
def update
params[:project].delete(:maintainer_id) if params[:project][:maintainer_id].blank?
- if @project.update_attributes(params[:project])
- flash[:notice] = t('flash.project.saved')
- redirect_to @project
+ respond_to do |format|
+ format.html do
+ if @project.update_attributes(params[:project])
+ flash[:notice] = t('flash.project.saved')
+ redirect_to @project
+ else
+ @project.save
+ flash[:error] = t('flash.project.save_error')
+ flash[:warning] = @project.errors.full_messages.join('. ')
+ render action: :edit
+ end
+ end
+ format.json do
+ if @project.update_attributes(params[:project])
+ render json: { notice: I18n.t('flash.project.saved') }.to_json
+ else
+ render json: { error: I18n.t('flash.project.save_error') }.to_json, status: 422
+ end
+ end
+ end
+ end
+
+ def schedule
+ p_to_r = @project.project_to_repositories.where(repository_id: params[:repository_id]).first
+ unless p_to_r.repository.publish_without_qa
+ authorize! :local_admin_manage, p_to_r.repository.platform
+ end
+ p_to_r.user_id = current_user.id
+ p_to_r.enabled = params[:enabled].present?
+ p_to_r.auto_publish = params[:auto_publish].present?
+ p_to_r.save
+ if p_to_r.save
+ render json: { notice: I18n.t('flash.project.saved') }.to_json
else
- @project.save
- flash[:error] = t('flash.project.save_error')
- flash[:warning] = @project.errors.full_messages.join('. ')
- render action: :edit
+ render json: { error: I18n.t('flash.project.save_error') }.to_json, status: 422
end
end
@@ -15,9 +15,7 @@ def build_list_status_color(status)
end
def availables_main_platforms
- # Main platforms with repositories
- Platform.main.accessible_by(current_ability, :show)
- .includes(:repositories).where('repositories.id IS NOT NULL').order('platforms.name').uniq
+ Platform.availables_main_platforms current_user, current_ability
end
def save_to_repositories(project)
@@ -19,6 +19,22 @@ def options_for_filters(all_projects, groups, owners)
end.sort_by{ |f| f[:uname] }
end
+ def available_project_to_repositories(project)
+ project.project_to_repositories.includes(repository: :platform).select do |p_to_r|
+ p_to_r.repository.publish_without_qa ? true : can?(:local_admin_manage, p_to_r.repository.platform)
+ end.sort_by do |p_to_r|
+ "#{p_to_r.repository.platform.name}/#{p_to_r.repository.name}"
+ end.map do |p_to_r|
+ {
+ repository_name: "#{p_to_r.repository.platform.name}/#{p_to_r.repository.name}",
+ repository_path: platform_repository_path(p_to_r.repository.platform, p_to_r.repository),
+ auto_publish: p_to_r.auto_publish?,
+ enabled: p_to_r.enabled?,
+ repository_id: p_to_r.repository_id
+ }
+ end.to_a.to_json
+ end
+
def repositories_grouped_by_platform
groups = {}
Platform.accessible_by(current_ability, :related).order(:name).each do |platform|
View
@@ -66,7 +66,7 @@ def initialize(user)
can [:read, :archive, :membered, :get_id], Project, owner_type: 'Group', owner_id: user_group_ids
can([:read, :archive, :membered, :get_id], Project, read_relations_for('projects')) {|project| local_reader? project}
can(:write, Project) {|project| local_writer? project} # for grack
- can [:update, :sections, :manage_collaborators, :autocomplete_maintainers, :add_member, :remove_member, :update_member, :members], Project do |project|
+ can [:update, :sections, :manage_collaborators, :autocomplete_maintainers, :add_member, :remove_member, :update_member, :members, :schedule], Project do |project|
local_admin? project
end
can(:fork, Project) {|project| can? :read, project}
View
@@ -243,6 +243,15 @@ def self.autostart_metadata_regeneration(value)
Platform.main.where(automatic_metadata_regeneration: value).each(&:regenerate)
end
+ def self.availables_main_platforms(user, ability = nil)
+ p_ids = Rails.cache.fetch([:availables_main_platforms, user], expires_in: 10.minutes) do
+ ability ||= Ability.new user
+ Platform.main.accessible_by(ability, :show).joins(:repositories).
+ where('repositories.id IS NOT NULL').uniq.pluck(:id)
+ end
+ Platform.preload(:repositories).where(id: p_ids).order(:name)
+ end
+
protected
def create_directory
View
@@ -1,26 +1,14 @@
class Product < ActiveRecord::Base
include Modules::Models::TimeLiving
+ include Modules::Models::Autostart
belongs_to :platform
belongs_to :project
has_many :product_build_lists, dependent: :destroy
- ONCE_A_12_HOURS = 0
- ONCE_A_DAY = 1
- ONCE_A_WEEK = 2
-
- AUTOSTART_STATUSES = [ONCE_A_12_HOURS, ONCE_A_DAY, ONCE_A_WEEK]
- HUMAN_AUTOSTART_STATUSES = {
- ONCE_A_12_HOURS => :once_a_12_hours,
- ONCE_A_DAY => :once_a_day,
- ONCE_A_WEEK => :once_a_week
- }
-
validates :name, presence: true, uniqueness: {scope: :platform_id}
validates :project_id, presence: true
validates :main_script, :params, length: { maximum: 255 }
- validates :autostart_status, numericality: true,
- inclusion: {in: AUTOSTART_STATUSES}, allow_blank: true
scope :recent, order("#{table_name}.name ASC")
@@ -30,7 +18,6 @@ class Product < ActiveRecord::Base
:main_script,
:params,
:platform_id,
- :autostart_status,
:project_version
attr_readonly :platform_id
@@ -44,16 +31,8 @@ def full_clone(attrs = {})
end
end
- def human_autostart_status
- self.class.human_autostart_status(autostart_status)
- end
-
- def self.human_autostart_status(autostart_status)
- I18n.t("layout.products.autostart_statuses.#{HUMAN_AUTOSTART_STATUSES[autostart_status]}")
- end
-
class << self
- HUMAN_AUTOSTART_STATUSES.each do |autostart_status, human_autostart_status|
+ Modules::Models::Autostart::HUMAN_AUTOSTART_STATUSES.each do |autostart_status, human_autostart_status|
define_method "autostart_iso_builds_#{human_autostart_status}" do
autostart_iso_builds autostart_status
end
View
@@ -1,4 +1,6 @@
class Project < ActiveRecord::Base
+ include Modules::Models::Autostart
+
VISIBILITIES = ['open', 'hidden']
MAX_OWN_PROJECTS = 32000
NAME_REGEXP = /[\w\-\+\.]+/
@@ -47,7 +49,8 @@ class Project < ActiveRecord::Base
attr_accessible :name, :description, :visibility, :srpm, :is_package, :default_branch,
:has_issues, :has_wiki, :maintainer_id, :publish_i686_into_x86_64,
- :url, :srpms_list, :mass_import, :add_to_repository_id, :architecture_dependent
+ :url, :srpms_list, :mass_import, :add_to_repository_id, :architecture_dependent,
+ :autostart_status
attr_readonly :owner_id, :owner_type
scope :recent, order("lower(#{table_name}.name) ASC")
@@ -168,16 +171,10 @@ def build_for(mass_build, repository_id, arch = Arch.find_by_name('i586'), prio
# 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 = build_for_platform.repositories.find_by_name(%w(main base)).try(:id)
+ main_rep_id = build_for_platform.repositories.main.first.try(:id)
include_repos = ([main_rep_id] << (save_to_platform.main? ? repository_id : nil)).compact.uniq
- 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
+ project_version = project_version_for save_to_platform, build_for_platform
increase_release_tag(project_version, user, "MassBuild##{mass_build.id}: Increase release tag") if increase_rt
@@ -199,6 +196,16 @@ def build_for(mass_build, repository_id, arch = Arch.find_by_name('i586'), prio
build_list.save
end
+ def project_version_for(save_to_platform, build_for_platform)
+ 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
+ end
+
def fork(new_owner, new_name = name)
new_name = new_name.presence || name
dup.tap do |c|
@@ -290,6 +297,44 @@ def self.replace_release_tag(content)
end
end
+ class << self
+ Modules::Models::Autostart::HUMAN_AUTOSTART_STATUSES.each do |autostart_status, human_autostart_status|
+ define_method "autostart_build_lists_#{human_autostart_status}" do
+ autostart_build_lists autostart_status
+ end
+ end
+ end
+
+ def self.autostart_build_lists(autostart_status)
+ Project.where(autostart_status: autostart_status).find_each do |p|
+ p.project_to_repositories.autostart_enabled.includes(repository: :platform).each do |p_to_r|
+ repository = p_to_r.repository
+ user = User.find(p_to_r.user_id)
+ if repository.platform.personal?
+ platforms = Platform.availables_main_platforms(user)
+ else
+ platforms = [repository.platform]
+ end
+ platforms.each do |platform|
+ platform.platform_arch_settings.by_default.pluck(:arch_id).each do |arch_id|
+ build_list = p.build_lists.build do |bl|
+ bl.save_to_platform = repository.platform
+ bl.build_for_platform = platform
+ bl.update_type = 'newpackage'
+ bl.arch_id = arch_id
+ bl.project_version = p.project_version_for(platform, platform)
+ bl.user = user
+ bl.auto_publish = p_to_r.auto_publish?
+ bl.save_to_repository = repository
+ bl.include_repos = [repository.id, platform.repositories.main.first.try(:id)].uniq.compact
+ end
+ build_list.save!
+ end
+ end
+ end
+ end
+ end
+
protected
def increase_release_tag(project_version, user, message)
@@ -1,13 +1,30 @@
class ProjectToRepository < ActiveRecord::Base
+ AUTOSTART_OPTIONS = %w(auto_publish user_id enabled)
+
belongs_to :project
belongs_to :repository
delegate :path, to: :project
+ scope :autostart_enabled, lambda { where("autostart_options -> 'enabled' = 'true'") }
+
after_destroy lambda { project.destroy_project_from_repository(repository) }, unless: lambda {Thread.current[:skip]}
validate :one_project_in_platform_repositories, on: :create
+ serialize :autostart_options, ActiveRecord::Coders::Hstore
+ AUTOSTART_OPTIONS.each do |field|
+ store_accessor :autostart_options, field
+ end
+
+ def enabled?
+ ['true', true].include?(enabled)
+ end
+
+ def auto_publish?
+ ['true', true].include?(auto_publish)
+ end
+
protected
def one_project_in_platform_repositories
View
@@ -1,6 +1,6 @@
class Relation < ActiveRecord::Base
belongs_to :target, polymorphic: true
- belongs_to :actor, polymorphic: true
+ belongs_to :actor, polymorphic: true, touch: true
ROLES = %w[reader writer admin]
validates :role, inclusion: {in: ROLES}
Oops, something went wrong.

0 comments on commit 72ee8f4

Please sign in to comment.