octopusci 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. data/README.markdown +132 -0
  2. data/bin/octopusci-reset-redis +26 -0
  3. data/bin/octopusci-skel +2 -7
  4. data/bin/octopusci-tentacles +2 -2
  5. data/config.ru +1 -1
  6. data/lib/octopusci.rb +3 -7
  7. data/lib/octopusci/config.rb +63 -49
  8. data/lib/octopusci/errors.rb +2 -0
  9. data/lib/octopusci/helpers.rb +16 -15
  10. data/lib/octopusci/io.rb +70 -0
  11. data/lib/octopusci/job.rb +145 -34
  12. data/lib/octopusci/job_store.rb +67 -0
  13. data/lib/octopusci/notifier.rb +7 -17
  14. data/lib/octopusci/notifier/job_complete.html.erb +76 -3
  15. data/lib/octopusci/queue.rb +14 -10
  16. data/lib/octopusci/server.rb +17 -20
  17. data/lib/octopusci/server/views/index.erb +3 -4
  18. data/lib/octopusci/server/views/job.erb +3 -3
  19. data/lib/octopusci/server/views/job_summary.erb +18 -18
  20. data/lib/octopusci/server/views/layout.erb +6 -5
  21. data/lib/octopusci/stage_locker.rb +11 -7
  22. data/lib/octopusci/version.rb +1 -1
  23. data/lib/octopusci/worker_launcher.rb +1 -1
  24. data/spec/lib/octopusci/config_spec.rb +195 -0
  25. data/spec/lib/octopusci/io_spec.rb +64 -0
  26. data/spec/lib/octopusci/job_spec.rb +122 -0
  27. data/spec/lib/octopusci/job_store_spec.rb +155 -0
  28. data/spec/lib/octopusci/notifier_spec.rb +0 -15
  29. data/spec/lib/octopusci/queue_spec.rb +122 -0
  30. data/spec/lib/octopusci/server_spec.rb +92 -1
  31. data/spec/lib/octopusci/stage_locker_spec.rb +94 -0
  32. data/spec/spec_helper.rb +8 -0
  33. metadata +39 -58
  34. data/README +0 -63
  35. data/bin/octopusci-db-migrate +0 -10
  36. data/db/migrate/0001_init.rb +0 -29
  37. data/db/migrate/0002_add_status_job.rb +0 -19
  38. data/lib/octopusci/notifier/job_complete.text.erb +0 -5
  39. data/lib/octopusci/schema.rb +0 -140
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Octopusci::StageLocker" do
4
+ describe "#load" do
5
+ it "should clear the pool of stages" do
6
+ @mock_redis.stub(:rpush)
7
+ Octopusci::StageLocker.should_receive(:clear)
8
+ Octopusci::StageLocker.load(['a', 'b', 'c'])
9
+ end
10
+
11
+ it "should push each of the provided stages into the stage pool" do
12
+ Octopusci::StageLocker.stub(:clear)
13
+ Octopusci::StageLocker.should_receive(:push).with('a')
14
+ Octopusci::StageLocker.should_receive(:push).with('b')
15
+ Octopusci::StageLocker.should_receive(:push).with('c')
16
+ Octopusci::StageLocker.load(['a', 'b', 'c'])
17
+ end
18
+ end
19
+
20
+ describe "#clear" do
21
+ it "should clear all of the stages out of the stage locker" do
22
+ r = mock('redis')
23
+ Octopusci::StageLocker.stub(:redis).and_return(r)
24
+ r.should_receive(:del).with('octopusci:stagelocker')
25
+ Octopusci::StageLocker.clear
26
+ end
27
+ end
28
+
29
+ describe "#pop" do
30
+ it "should pop the left most stage out of the stage locker" do
31
+ r = mock('redis')
32
+ Octopusci::StageLocker.stub(:redis).and_return(r)
33
+ r.should_receive(:lpop).with('octopusci:stagelocker')
34
+ Octopusci::StageLocker.pop
35
+ end
36
+ end
37
+
38
+ describe "#rem" do
39
+ it "should remove the provided stage from the stage locker pool" do
40
+ r = mock('redis')
41
+ Octopusci::StageLocker.stub(:redis).and_return(r)
42
+ r.should_receive(:lrem).with('octopusci:stagelocker', 1, 'a')
43
+ Octopusci::StageLocker.rem('a')
44
+ end
45
+ end
46
+
47
+ describe "#push" do
48
+ it "should append the provided stage to the right of the stage locker" do
49
+ r = mock('redis')
50
+ Octopusci::StageLocker.stub(:redis).and_return(r)
51
+ r.should_receive(:rpush).with('octopusci:stagelocker', 'a')
52
+ Octopusci::StageLocker.push('a')
53
+ end
54
+ end
55
+
56
+ describe "#stages" do
57
+ it "should return the defined stages from the configuration" do
58
+ Octopusci::Config.should_receive(:[]).with('stages').and_return(['a', 'b', 'c', 'd'])
59
+ Octopusci::StageLocker.stages.should == ['a', 'b', 'c', 'd']
60
+ end
61
+ end
62
+
63
+ describe "#pool" do
64
+ it "should return the pool of stages" do
65
+ r = stub('redis').as_null_object
66
+ Octopusci::StageLocker.stub(:redis).and_return(r)
67
+ r.stub(:peek).and_return(['stage_a', 'stage_b', 'stage_c'])
68
+ Octopusci::StageLocker.pool.should == ['stage_a', 'stage_b', 'stage_c']
69
+ end
70
+
71
+ it "should get the size of the current pool stored in redis" do
72
+ r = mock('redis').as_null_object
73
+ Octopusci::StageLocker.stub(:redis).and_return(r)
74
+ r.should_receive(:size).with('octopusci:stagelocker')
75
+ Octopusci::StageLocker.pool
76
+ end
77
+
78
+ it "should get the current pool of stages stored in redis" do
79
+ r = mock('redis')
80
+ Octopusci::StageLocker.stub(:redis).and_return(r)
81
+ r.stub(:size).and_return(4)
82
+ r.should_receive(:peek).with('octopusci:stagelocker', 0, 4)
83
+ Octopusci::StageLocker.pool
84
+ end
85
+ end
86
+
87
+ describe "#redis" do
88
+ it "should return redis instance provided by resqueue" do
89
+ r = stub('redis')
90
+ Resque.should_receive(:redis).and_return(r)
91
+ Octopusci::StageLocker.redis.should == r
92
+ end
93
+ end
94
+ end
@@ -9,3 +9,11 @@ def app
9
9
  end
10
10
 
11
11
  include Rack::Test::Methods
12
+
13
+ RSpec.configure do |config|
14
+ config.before(:each) do
15
+ # Here I mock the Resque redis method to prevent the tests from actually storing any data in redis
16
+ @mock_redis = mock('redis')
17
+ Resque.stub(:redis).and_return(@mock_redis)
18
+ end
19
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: octopusci
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-10-13 00:00:00.000000000Z
13
+ date: 2011-11-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sinatra
17
- requirement: &70141088955920 !ruby/object:Gem::Requirement
17
+ requirement: &70256773373660 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70141088955920
25
+ version_requirements: *70256773373660
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: json
28
- requirement: &70141088955500 !ruby/object:Gem::Requirement
28
+ requirement: &70256773372560 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *70141088955500
36
+ version_requirements: *70256773372560
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: resque
39
- requirement: &70141088955080 !ruby/object:Gem::Requirement
39
+ requirement: &70256773372040 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *70141088955080
47
+ version_requirements: *70256773372040
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: actionmailer
50
- requirement: &70141088954660 !ruby/object:Gem::Requirement
50
+ requirement: &70256773371540 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,32 +55,10 @@ dependencies:
55
55
  version: '0'
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *70141088954660
59
- - !ruby/object:Gem::Dependency
60
- name: activerecord
61
- requirement: &70141088954240 !ruby/object:Gem::Requirement
62
- none: false
63
- requirements:
64
- - - ! '>='
65
- - !ruby/object:Gem::Version
66
- version: '0'
67
- type: :runtime
68
- prerelease: false
69
- version_requirements: *70141088954240
70
- - !ruby/object:Gem::Dependency
71
- name: mysql
72
- requirement: &70141088953820 !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ! '>='
76
- - !ruby/object:Gem::Version
77
- version: '0'
78
- type: :runtime
79
- prerelease: false
80
- version_requirements: *70141088953820
58
+ version_requirements: *70256773371540
81
59
  - !ruby/object:Gem::Dependency
82
60
  name: multi_json
83
- requirement: &70141088953400 !ruby/object:Gem::Requirement
61
+ requirement: &70256773370980 !ruby/object:Gem::Requirement
84
62
  none: false
85
63
  requirements:
86
64
  - - ! '>='
@@ -88,10 +66,10 @@ dependencies:
88
66
  version: '0'
89
67
  type: :runtime
90
68
  prerelease: false
91
- version_requirements: *70141088953400
69
+ version_requirements: *70256773370980
92
70
  - !ruby/object:Gem::Dependency
93
71
  name: time-ago-in-words
94
- requirement: &70141088952980 !ruby/object:Gem::Requirement
72
+ requirement: &70256773369660 !ruby/object:Gem::Requirement
95
73
  none: false
96
74
  requirements:
97
75
  - - ! '>='
@@ -99,10 +77,10 @@ dependencies:
99
77
  version: '0'
100
78
  type: :runtime
101
79
  prerelease: false
102
- version_requirements: *70141088952980
80
+ version_requirements: *70256773369660
103
81
  - !ruby/object:Gem::Dependency
104
82
  name: rake
105
- requirement: &70141088952560 !ruby/object:Gem::Requirement
83
+ requirement: &70256773368320 !ruby/object:Gem::Requirement
106
84
  none: false
107
85
  requirements:
108
86
  - - ! '>='
@@ -110,10 +88,10 @@ dependencies:
110
88
  version: '0'
111
89
  type: :development
112
90
  prerelease: false
113
- version_requirements: *70141088952560
91
+ version_requirements: *70256773368320
114
92
  - !ruby/object:Gem::Dependency
115
93
  name: rspec
116
- requirement: &70141088952140 !ruby/object:Gem::Requirement
94
+ requirement: &70256773367880 !ruby/object:Gem::Requirement
117
95
  none: false
118
96
  requirements:
119
97
  - - ! '>='
@@ -121,10 +99,10 @@ dependencies:
121
99
  version: '0'
122
100
  type: :development
123
101
  prerelease: false
124
- version_requirements: *70141088952140
102
+ version_requirements: *70256773367880
125
103
  - !ruby/object:Gem::Dependency
126
104
  name: rack-test
127
- requirement: &70141088972180 !ruby/object:Gem::Requirement
105
+ requirement: &70256773367280 !ruby/object:Gem::Requirement
128
106
  none: false
129
107
  requirements:
130
108
  - - ! '>='
@@ -132,10 +110,10 @@ dependencies:
132
110
  version: '0'
133
111
  type: :development
134
112
  prerelease: false
135
- version_requirements: *70141088972180
113
+ version_requirements: *70256773367280
136
114
  - !ruby/object:Gem::Dependency
137
115
  name: guard
138
- requirement: &70141088971760 !ruby/object:Gem::Requirement
116
+ requirement: &70256773366640 !ruby/object:Gem::Requirement
139
117
  none: false
140
118
  requirements:
141
119
  - - ! '>='
@@ -143,10 +121,10 @@ dependencies:
143
121
  version: '0'
144
122
  type: :development
145
123
  prerelease: false
146
- version_requirements: *70141088971760
124
+ version_requirements: *70256773366640
147
125
  - !ruby/object:Gem::Dependency
148
126
  name: rb-fsevent
149
- requirement: &70141088971340 !ruby/object:Gem::Requirement
127
+ requirement: &70256773365960 !ruby/object:Gem::Requirement
150
128
  none: false
151
129
  requirements:
152
130
  - - ! '>='
@@ -154,10 +132,10 @@ dependencies:
154
132
  version: '0'
155
133
  type: :development
156
134
  prerelease: false
157
- version_requirements: *70141088971340
135
+ version_requirements: *70256773365960
158
136
  - !ruby/object:Gem::Dependency
159
- name: growl
160
- requirement: &70141088970920 !ruby/object:Gem::Requirement
137
+ name: growl_notify
138
+ requirement: &70256773365160 !ruby/object:Gem::Requirement
161
139
  none: false
162
140
  requirements:
163
141
  - - ! '>='
@@ -165,10 +143,10 @@ dependencies:
165
143
  version: '0'
166
144
  type: :development
167
145
  prerelease: false
168
- version_requirements: *70141088970920
146
+ version_requirements: *70256773365160
169
147
  - !ruby/object:Gem::Dependency
170
148
  name: guard-rspec
171
- requirement: &70141088970500 !ruby/object:Gem::Requirement
149
+ requirement: &70256773364400 !ruby/object:Gem::Requirement
172
150
  none: false
173
151
  requirements:
174
152
  - - ! '>='
@@ -176,7 +154,7 @@ dependencies:
176
154
  version: '0'
177
155
  type: :development
178
156
  prerelease: false
179
- version_requirements: *70141088970500
157
+ version_requirements: *70256773364400
180
158
  description: A multi-branch Continous Integration server that integrates with GitHub
181
159
  email:
182
160
  - cyphactor@gmail.com
@@ -184,22 +162,21 @@ email:
184
162
  executables:
185
163
  - octopusci-tentacles
186
164
  - octopusci-skel
187
- - octopusci-db-migrate
188
165
  extensions: []
189
166
  extra_rdoc_files: []
190
167
  files:
191
- - README
168
+ - README.markdown
192
169
  - LICENSE
193
170
  - config.ru
194
171
  - lib/octopusci/config.rb
195
172
  - lib/octopusci/errors.rb
196
173
  - lib/octopusci/helpers.rb
174
+ - lib/octopusci/io.rb
197
175
  - lib/octopusci/job.rb
176
+ - lib/octopusci/job_store.rb
198
177
  - lib/octopusci/notifier/job_complete.html.erb
199
- - lib/octopusci/notifier/job_complete.text.erb
200
178
  - lib/octopusci/notifier.rb
201
179
  - lib/octopusci/queue.rb
202
- - lib/octopusci/schema.rb
203
180
  - lib/octopusci/server/public/images/ajax-loader-1.gif
204
181
  - lib/octopusci/server/public/images/noise.gif
205
182
  - lib/octopusci/server/public/images/status.png
@@ -216,16 +193,20 @@ files:
216
193
  - lib/octopusci/worker_launcher.rb
217
194
  - lib/octopusci.rb
218
195
  - bin/octopusci
219
- - bin/octopusci-db-migrate
196
+ - bin/octopusci-reset-redis
220
197
  - bin/octopusci-skel
221
198
  - bin/octopusci-tentacles
222
199
  - bin/pusci-stage
200
+ - spec/lib/octopusci/config_spec.rb
201
+ - spec/lib/octopusci/io_spec.rb
202
+ - spec/lib/octopusci/job_spec.rb
203
+ - spec/lib/octopusci/job_store_spec.rb
223
204
  - spec/lib/octopusci/notifier_spec.rb
205
+ - spec/lib/octopusci/queue_spec.rb
224
206
  - spec/lib/octopusci/server_spec.rb
207
+ - spec/lib/octopusci/stage_locker_spec.rb
225
208
  - spec/lib/octopusci_spec.rb
226
209
  - spec/spec_helper.rb
227
- - db/migrate/0001_init.rb
228
- - db/migrate/0002_add_status_job.rb
229
210
  - extra/etc/init.d/octopusci
230
211
  homepage: https://github.com/cyphactor/octopusci
231
212
  licenses: []
data/README DELETED
@@ -1,63 +0,0 @@
1
- The purpose of this project is provide a simple CI server that will work with
2
- GitHub Post-Receive hook. It is also specifically designed to handle multiple
3
- build/job queues for each branch.
4
-
5
- This would basically allow you to every time code is pushed to the central
6
- repository enqueue a build/job for the specific branch. That way if you
7
- have topic branches that are being pushed to the central repository along
8
- side the mainline branch they will get queue properly as well.
9
-
10
- My idea for implementation at this point is that if I can detect the branch
11
- from the GitHub Post-Receive hook then I can identify branch. If I can
12
- identify branch then I can maintain individual queues for each branch.
13
-
14
- Then the execution would look at config values for predefined branches and
15
- priorities for order of running them so that the mainline branch running its
16
- jobs could take precedence over non specified topic branches.
17
-
18
- Install redis and get it starting up appropriately
19
-
20
- gem install octopusci
21
- sudo octopusci-skel
22
- octopusci-db-migrate
23
-
24
- Then update the /etc/octopusci/config.yml appropriately.
25
-
26
- Add any jobs you would like to the /etc/octopusci/jobs directory as rb files
27
- and octopusci will load them appropriately when started.
28
-
29
- Figure out what directory the gem is installed in by running the following
30
- command and stripping off the lib/octopusci.rb at the end.
31
-
32
- gem which octopusci
33
-
34
- Once you have the path we can use that path to setup Passenger with Apache
35
- or something else like nginx as well as setup the database. Note: You will
36
- need to setup a database user and a database for octopusci. The settings for
37
- these should be stored in /etc/octopusci/config.yml.
38
-
39
- rake -f /path/of/octpusci/we/got/before/Rakefile db:migrate
40
-
41
- <VirtualHost *:80>
42
- ServerName octopusci.example.com
43
- PassengerAppRoot /path/of/octpusci/we/got/before
44
- DocumentRoot /path/of/octpusci/we/got/before/lib/octopusci/server/public
45
- <Directory /path/of/octpusci/we/got/before/lib/octopusci/server/public>
46
- Order allow,deny
47
- Allow from all
48
- AllowOverride all
49
- Options -MultiViews
50
- </Directory>
51
- </VirtualHost>
52
-
53
- The above will give us the web Octopusci web interface.
54
-
55
- If you are developing you can simply start this up by running
56
- rackup -p whatever_port while inside the octopusci directory where the
57
- config.ru file exists.
58
-
59
- I recommend you setup the second half of Octopusci (octopusci-tentacles) with
60
- God or some other monitoring system. However, for development you can simply
61
- run octopusci-tentacles directoly as follows:
62
-
63
- otopusci-tentacles
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
4
-
5
- require 'rubygems'
6
- require 'octopusci'
7
-
8
- ActiveRecord::Base.logger = Logger.new(STDOUT)
9
- ActiveRecord::Migration.verbose = true
10
- ActiveRecord::Migrator.migrate(File.expand_path(File.dirname(__FILE__) + "/../db/migrate"))
@@ -1,29 +0,0 @@
1
- class Init < ActiveRecord::Migration
2
- def self.up
3
- create_table :jobs do |t|
4
- t.string :ref
5
- t.string :compare
6
- t.string :repo_name
7
- t.string :repo_owner_name
8
- t.string :repo_owner_email
9
- t.timestamp :repo_pushed_at
10
- t.timestamp :repo_created_at
11
- t.text :repo_desc
12
- t.string :repo_url
13
- t.string :before_commit
14
- t.boolean :forced
15
- t.string :after_commit
16
- t.boolean :running
17
- t.boolean :successful
18
- t.text :output
19
- t.timestamps
20
- t.timestamp :started_at
21
- t.timestamp :ended_at
22
- t.text :payload
23
- end
24
- end
25
-
26
- def self.down
27
- drop_table :jobs
28
- end
29
- end