Skip to content
Snippets Groups Projects
Commit 874a71ec authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets
Browse files

Merge branch 'master' of https://github.com/mrichie/gitlab-ci into mrichie-master

parents 0943fe88 34e6ccbd
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -7,3 +7,5 @@ tmp/*
/.bundle
/db/*.sqlite3
/log/*.log
.powrc
.rvmrc
Loading
Loading
@@ -27,6 +27,7 @@ gem 'haml-rails'
 
# Jobs
gem 'resque'
gem 'resque-scheduler', :require => 'resque_scheduler'
 
# Format dates
gem 'stamp'
Loading
Loading
Loading
Loading
@@ -155,6 +155,10 @@ GEM
redis-namespace (~> 1.0)
sinatra (>= 0.9.2)
vegas (~> 0.1.2)
resque-scheduler (2.0.0)
redis (>= 2.0.1)
resque (>= 1.20.0)
rufus-scheduler
rspec (2.11.0)
rspec-core (~> 2.11.0)
rspec-expectations (~> 2.11.0)
Loading
Loading
@@ -169,6 +173,8 @@ GEM
railties (>= 3.0)
rspec (~> 2.11.0)
rubyzip (0.9.9)
rufus-scheduler (2.0.17)
tzinfo (>= 0.3.23)
sass (3.2.1)
sass-rails (3.2.5)
railties (~> 3.2.0)
Loading
Loading
@@ -243,6 +249,7 @@ DEPENDENCIES
rb-fsevent
rb-inotify
resque
resque-scheduler
rspec-rails
sass-rails (~> 3.2.3)
settingslogic
Loading
Loading
class Project < ActiveRecord::Base
attr_accessible :name, :path, :scripts, :timeout, :token, :default_ref, :gitlab_url
attr_accessible :name, :path, :scripts, :timeout, :token, :default_ref, :gitlab_url, :always_build, :polling_interval
 
validates_presence_of :name, :path, :scripts, :timeout, :token, :default_ref
 
validates :polling_interval, :format => { :with => /^[1-9]\d{0,7}[s|m|d]$/ }, :unless => Proc.new{|project| project.polling_interval.blank?}
has_many :builds, dependent: :destroy
 
validate :repo_present?
Loading
Loading
@@ -10,6 +12,7 @@ class Project < ActiveRecord::Base
validates_uniqueness_of :name
 
before_validation :set_default_values
after_save :set_scheduler
 
def set_default_values
self.token = SecureRandom.hex(15) if self.token.blank?
Loading
Loading
@@ -113,6 +116,20 @@ class Project < ActiveRecord::Base
def valid_token? token
self.token && self.token == token
end
def set_scheduler
if self.polling_interval.present?
Resque.set_schedule(self.token, {
:class => 'SchedulerJob',
:every => self.polling_interval,
:queue => 'scheduler_task',
:args => [:run, self.id],
:description => self.name
})
else
Resque.remove_schedule(self.token)
end
end
end
 
 
Loading
Loading
@@ -130,4 +147,3 @@ end
# token :string(255)
# default_ref :string(255)
#
Loading
Loading
@@ -17,6 +17,13 @@
.field
= f.label :token, "Token (Leave empty to generate random token)"
= f.text_field :token, class: 'input-xlarge', placeholder: 'xEeFCaDAB89'
.field
= f.label :always_build, "Always_build"
= f.check_box :always_build
.field
= f.label :polling_interval, "Polling_interval"
= f.text_field :polling_interval
%fieldset
%legend Git
.field
Loading
Loading
require Rails.root.join('lib', 'runner')
#require Rails.root.join('lib', 'scheduler_job')
require 'scheduler_job'
 
# Custom Redis configuration
config_file = Rails.root.join('config', 'resque.yml')
Loading
Loading
GitlabCi::Application.routes.draw do
# Optionally, enable Resque here
require 'resque/server'
require 'resque_scheduler'
require 'resque_scheduler/server'
mount Resque::Server => '/ext/resque', as: 'ext_resque'
 
resources :projects do
Loading
Loading
class AddScheduleToProjects < ActiveRecord::Migration
def change
add_column :projects, :always_build, :boolean, :default => true
add_column :projects, :polling_interval, :string
end
end
class SchedulerJob
@queue = :scheduler_task
def self.perform(method, *args)
self.send(method, *args)
end
# run scheduler job
def self.run(project_id)
@project = Project.find(project_id)
# when always_build not checked, do not build project in schedule if project not updated
return if !@project.always_build && (@project.builds.last.sha == @project.last_ref_sha(@project.default_ref))
# always_build not checked and project updated, build it
# always_build checked and no matter project updated or not, build it
@build = @project.register_build(ref: @project.default_ref)
if @build and @build.id
Runner.new(Build.find(@build.id)).run
end
end
end
require 'resque/tasks'
require 'resque_scheduler/tasks'
namespace :resque do
task :setup => :environment do
require 'resque'
require 'resque_scheduler'
#require 'resque_scheduler/server'
#require 'resque/scheduler'
# you probably already have this somewhere
#Resque.redis = 'localhost:6379'
# If you want to be able to dynamically change the schedule,
# uncomment this line. A dynamic schedule can be updated via the
# Resque::Scheduler.set_schedule (and remove_schedule) methods.
# When dynamic is set to true, the scheduler process looks for
# schedule changes and applies them on the fly.
# Note: This feature is only available in >=2.0.0.
Resque::Scheduler.dynamic = true
# The schedule doesn't need to be stored in a YAML, it just needs to
# be a hash. YAML is usually the easiest.
#Resque.schedule = YAML.load_file('your_resque_schedule.yml')
# If your schedule already has +queue+ set for each job, you don't
# need to require your jobs. This can be an advantage since it's
# less code that resque-scheduler needs to know about. But in a small
# project, it's usually easier to just include you job classes here.
# So, something like this:
#require 'jobs'
end
end
mkdir -p tmp/pids
nohup bundle exec rake environment resque:work QUEUE=runner,scheduler_task VVERBOSE=1 RAILS_ENV=development PIDFILE=tmp/pids/resque_worker.pid > ./log/resque.log &
nohup bundle exec rake environment resque:scheduler VVERBOSE=1 RAILS_ENV=development PIDFILE=tmp/pids/resque_schedule.pid > ./log/schedule.log &
Loading
Loading
@@ -22,6 +22,33 @@ describe Project do
end
end
 
describe 'after_save_with_schedule' do
it 'should not set schedule if polling_interval is blank' do
project = FactoryGirl.create :project
project.update_attribute(:polling_interval, nil)
Resque.get_schedule(project.token).should be_nil
end
it 'should set schedule if polling_interval is set' do
project = FactoryGirl.create :project
project.update_attribute(:polling_interval, '3m')
Resque.get_schedule(project.token).should.to_s == {
:class => 'SchedulerJob',
:every => project.polling_interval,
:args => [:run, project.id],
:description => project.name
}.to_s
end
it 'should cancel schedule if clear polling_interval' do
project = FactoryGirl.create :project
project.update_attribute(:polling_interval, '3m')
Resque.get_schedule(project.token).should_not be_nil
project.update_attribute(:polling_interval, nil)
Resque.get_schedule(project.token).should be_nil
end
end
it { should validate_presence_of :name }
it { should validate_presence_of :scripts }
it { should validate_presence_of :timeout }
Loading
Loading
@@ -67,4 +94,3 @@ end
# token :string(255)
# default_ref :string(255)
#
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment