torquebox-stompbox 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock ADDED
@@ -0,0 +1,144 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.2.5)
5
+ backports (2.0.3)
6
+ bcrypt-ruby (2.1.4-java)
7
+ data_mapper (1.1.0)
8
+ dm-aggregates (= 1.1.0)
9
+ dm-constraints (= 1.1.0)
10
+ dm-core (= 1.1.0)
11
+ dm-migrations (= 1.1.0)
12
+ dm-serializer (= 1.1.0)
13
+ dm-timestamps (= 1.1.0)
14
+ dm-transactions (= 1.1.0)
15
+ dm-types (= 1.1.0)
16
+ dm-validations (= 1.1.0)
17
+ data_objects (0.10.3)
18
+ addressable (~> 2.1)
19
+ diff-lcs (1.1.2)
20
+ dm-aggregates (1.1.0)
21
+ dm-core (~> 1.1.0)
22
+ dm-constraints (1.1.0)
23
+ dm-core (~> 1.1.0)
24
+ dm-core (1.1.0)
25
+ addressable (~> 2.2.4)
26
+ dm-do-adapter (1.1.0)
27
+ data_objects (~> 0.10.2)
28
+ dm-core (~> 1.1.0)
29
+ dm-migrations (1.1.0)
30
+ dm-core (~> 1.1.0)
31
+ dm-observer (1.1.0)
32
+ dm-core (~> 1.1.0)
33
+ dm-postgres-adapter (1.1.0)
34
+ dm-do-adapter (~> 1.1.0)
35
+ do_postgres (~> 0.10.2)
36
+ dm-serializer (1.1.0)
37
+ dm-core (~> 1.1.0)
38
+ fastercsv (~> 1.5.4)
39
+ json (~> 1.4.6)
40
+ dm-timestamps (1.1.0)
41
+ dm-core (~> 1.1.0)
42
+ dm-transactions (1.1.0)
43
+ dm-core (~> 1.1.0)
44
+ dm-types (1.1.0)
45
+ bcrypt-ruby (~> 2.1.4)
46
+ dm-core (~> 1.1.0)
47
+ fastercsv (~> 1.5.4)
48
+ json (~> 1.4.6)
49
+ stringex (~> 1.2.0)
50
+ uuidtools (~> 2.1.2)
51
+ dm-validations (1.1.0)
52
+ dm-core (~> 1.1.0)
53
+ do_jdbc (0.10.3-java)
54
+ data_objects (= 0.10.3)
55
+ do_postgres (0.10.3-java)
56
+ data_objects (= 0.10.3)
57
+ do_jdbc (= 0.10.3)
58
+ jdbc-postgres (>= 8.2)
59
+ extlib (0.9.15)
60
+ fastercsv (1.5.4)
61
+ git (1.2.5)
62
+ haml (3.0.25)
63
+ jdbc-postgres (9.0.801)
64
+ jeweler (1.5.2)
65
+ bundler (~> 1.0.0)
66
+ git (>= 1.2.5)
67
+ rake
68
+ json (1.4.6-java)
69
+ json_pure (1.5.1)
70
+ monkey-lib (0.5.4)
71
+ backports
72
+ rack (1.2.2)
73
+ rack-flash (0.1.1)
74
+ rack
75
+ rack-test (0.5.7)
76
+ rack (>= 1.0)
77
+ rake (0.8.7)
78
+ rspec (2.5.0)
79
+ rspec-core (~> 2.5.0)
80
+ rspec-expectations (~> 2.5.0)
81
+ rspec-mocks (~> 2.5.0)
82
+ rspec-core (2.5.1)
83
+ rspec-expectations (2.5.0)
84
+ diff-lcs (~> 1.1.2)
85
+ rspec-mocks (2.5.0)
86
+ sinatra (1.1.2)
87
+ rack (~> 1.1)
88
+ tilt (~> 1.2)
89
+ sinatra-advanced-routes (0.5.1)
90
+ monkey-lib (~> 0.5.0)
91
+ sinatra (~> 1.0)
92
+ sinatra-sugar (~> 0.5.0)
93
+ sinatra-reloader (0.5.0)
94
+ sinatra (~> 1.0)
95
+ sinatra-advanced-routes (~> 0.5.0)
96
+ sinatra-sugar (0.5.0)
97
+ monkey-lib (~> 0.5.0)
98
+ sinatra (~> 1.0)
99
+ state_machine (0.10.3)
100
+ stringex (1.2.1)
101
+ thor (0.14.6)
102
+ tilt (1.2.2)
103
+ torquebox (1.0.0.CR1)
104
+ torquebox-base (= 1.0.0.CR1)
105
+ torquebox-messaging (= 1.0.0.CR1)
106
+ torquebox-naming (= 1.0.0.CR1)
107
+ torquebox-rake-support (= 1.0.0.CR1)
108
+ torquebox-vfs (= 1.0.0.CR1)
109
+ torquebox-web (= 1.0.0.CR1)
110
+ torquebox-base (1.0.0.CR1-java)
111
+ torquebox-messaging (1.0.0.CR1-java)
112
+ torquebox-base (= 1.0.0.CR1)
113
+ torquebox-naming (= 1.0.0.CR1)
114
+ torquebox-naming (1.0.0.CR1-java)
115
+ torquebox-rake-support (1.0.0.CR1)
116
+ torquebox-vfs (1.0.0.CR1-java)
117
+ torquebox-web (1.0.0.CR1-java)
118
+ uuidtools (2.1.2)
119
+
120
+ PLATFORMS
121
+ java
122
+
123
+ DEPENDENCIES
124
+ bundler
125
+ data_mapper (~> 1.1)
126
+ dm-core (~> 1.1)
127
+ dm-migrations (~> 1.1)
128
+ dm-observer (~> 1.1)
129
+ dm-postgres-adapter (~> 1.1)
130
+ dm-timestamps (~> 1.1)
131
+ extlib
132
+ git
133
+ haml (~> 3.0)
134
+ jeweler
135
+ json_pure
136
+ rack-flash (= 0.1.1)
137
+ rack-test
138
+ rake
139
+ rspec
140
+ sinatra (= 1.1.2)
141
+ sinatra-reloader (= 0.5.0)
142
+ state_machine
143
+ thor
144
+ torquebox (= 1.0.0.CR1)
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2010, Red Hat, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # StompBox : A Deployer for TorqueBox
2
+
3
+ StompBox is a simple Sinatra app that can be used to manage deployments on
4
+ [TorqueBox][torquebox] by accepting commit notifications from [GitHub][github].
5
+ It provides a user interface for managing one-click deployment and undeployment
6
+ of your github repositories to TorqueBox for specific branches and commit
7
+ points.
8
+
9
+ ## Why?
10
+
11
+ StompBox is useful for testing and development environments where your code is
12
+ changing frequently and you want to quickly deploy working branches and staging
13
+ instances. It integrates with your [GitHub][github] repositories to enable
14
+ extremely quick and simple app deployment of any Rack-based application. And
15
+ it does all this on top of the industrial-strength TorqueBox platform,
16
+ automatically providing your application with enterprise-level functionality
17
+ such as messaging, scheduling, tasks, clustering and more.
18
+
19
+ ## Installation
20
+
21
+ If you don't already have a TorqueBox instance installed, you should do that
22
+ first. Head on over to the [TorqueBox][torquebox] web site and follow the
23
+ detailed instructions for downloading, installing, configuring and running
24
+ TorqueBox. Don't worry - it's easy.
25
+
26
+ StompBox hasn't been tested on Windows and may not work in that environment.
27
+ However, if you are running a Unix-y system such as Fedora or Mac OSX, then you
28
+ should be fine.
29
+
30
+ Once you've installed TorqueBox, clone the StompBox repository, install the
31
+ gems, and deploy it to your running TorqueBox instance.
32
+
33
+ $ git clone git@github.com:lance/stompbox.git
34
+ Cloning into stompbox...
35
+ remote: Counting objects: 187, done.
36
+ remote: Compressing objects: 100% (168/168), done.
37
+ remote: Total 187 (delta 108), reused 0 (delta 0)
38
+ Receiving objects: 100% (187/187), 22.96 KiB, done.
39
+ Resolving deltas: 100% (108/108), done.
40
+
41
+ $ cd stompbox && bundle install
42
+ <output clipped for brevity - you should see this at the end>
43
+ Your bundle is complete! It was installed into /path/to/gem/home
44
+
45
+ $ rake torquebox:deploy
46
+
47
+ ## Configuration
48
+
49
+ Configuration options are found in config/torquebox.yml. Here are some things
50
+ you'll want to pay attention to.
51
+
52
+ * **DATABASE_URL** Provide a URI for connecting to your database. By convention,
53
+ StompBox uses a database called "stompbox", but you can change this to
54
+ whatever you want as long as it is supported by DataMapper. Be sure the user
55
+ specified in the connection URI has appropriate privileges for executing DDL
56
+ on your database. When the app starts for the first time, the tables will be
57
+ created and it will fail if your user doesn't have the proper permissions.
58
+
59
+ * **AUTO_MIGRATE** The first time you run StompBox, you'll want to have this on
60
+ so that your database is automagically created. After that, it's most efficient
61
+ to just unset this option by commenting it out.
62
+
63
+ * **DEPLOYMENTS** When you deploy an application using StompBox, it clones the
64
+ git repository into this directory. Make sure that your TorqueBox instance is
65
+ running as a user with enough privileges to write to this directory.
66
+
67
+ * **REQUIRE_AUTHENTICATION** To turn authentication on, set this to any non-nil
68
+ value. StompBox uses the built-in JAAS authentication provided by TorqueBox and
69
+ JBossAS. See the **Authentication** section below for more information.
70
+
71
+ * **API_KEY** This should be set to something unguessable like an SHA1 hash.
72
+ You can generate these any number of ways.
73
+
74
+ Here's one one way to generate a key.
75
+
76
+ $ echo "Now is the winter of our discontent made glorious summer by this son of York" | openssl sha1
77
+
78
+ (stdin)= e4ba3556d1d059e2eadca9488b093d6685657e00
79
+
80
+ ## Authentication
81
+
82
+ StompBox uses the built-in JAAS authentication provided by JBoss and exposed
83
+ via TorqueBox. If this is a development system (it probably should be), the
84
+ simplest way to set usernames and passwords is to use the builtin rake task.
85
+
86
+ $ rake torquebox:auth:adduser username:password
87
+
88
+ Be sure to set REQUIRE_AUTHENTICATION in config/torquebox.yml as well.
89
+ Voilá, authentication is enabled.
90
+
91
+ TorqueBox (and subsequently StompBox) can also authenticate with any other
92
+ realm you have configured in your JBossAS. If you have configured JAAS settings
93
+ in your TorqueBox instance, you may authenticate against them by supplying
94
+ the authentication realm in config/torquebox.yml as shown.
95
+
96
+ auth:
97
+ default:
98
+ domain: my-configured-jaas-realm
99
+
100
+ ## Usage
101
+
102
+ Start by telling StompBox what repositories and branches you want to track.
103
+ Once you've got everything configured and deployed, you can start by telling
104
+ StompBox what repositories and branches you want to track. Then, from
105
+ [GitHub][github], browse to the repository admin screen for one of the
106
+ repositories you specified in `config/stompbox.yml`. Select "Service Hooks" ->
107
+ "Post Receive URLs" and enter your StompBox URL plus your api_key (you
108
+ configured it didn't you?). It should look something like this.
109
+
110
+ http://mydomain.com/stompbox/push/3821A95D456134214FAD6FA91A2BAFE574D47151
111
+
112
+ After you save your settings, testing the service hook should send a POST
113
+ request to your StompBox. Play around.
114
+
115
+ ## Caveats
116
+
117
+ This project is very immature and there are many features which are outstanding (such as any real authentication). You should **not** use it in a production environment. It is currently used for research, development and testing only.
118
+
119
+ ## License
120
+
121
+ This software is distributed under an [MIT software license][license].
122
+
123
+ [torquebox]: http://torquebox.org "TorqueBox"
124
+ [github]: https://github.com "GitHub"
125
+ [license]: 'LICENSE.txt' "MIT License"
@@ -0,0 +1,55 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'torquebox'
18
+ require 'org/torquebox/auth/authentication'
19
+
20
+ module StompBox
21
+ module Authentication
22
+
23
+ def login_path
24
+ "#{request.script_name}/login"
25
+ end
26
+
27
+ def authenticated?
28
+ !session[:user].nil?
29
+ end
30
+
31
+ def authenticate(username, password)
32
+ return false if username.blank? || password.blank?
33
+ authenticator = TorqueBox::Authentication.default
34
+ authenticator.authenticate(username, password) do
35
+ session[:user] = username
36
+ end
37
+ end
38
+
39
+ def skip_authentication
40
+ request.env['SKIP_AUTH'] = true
41
+ end
42
+
43
+ def require_authentication
44
+ return if request.env['SKIP_AUTH']
45
+ return if authenticated?
46
+ redirect login_path
47
+ end
48
+
49
+ def logout
50
+ session[:user] = nil
51
+ redirect login_path
52
+ end
53
+
54
+ end
55
+ end
data/app/deployer.rb ADDED
@@ -0,0 +1,156 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'git'
18
+ require 'open3'
19
+ require 'models'
20
+ require 'torquebox-rake-support'
21
+ require 'torquebox/rake/tasks'
22
+ require 'app/tasks/deployer_task'
23
+
24
+ ENV['DEPLOYMENTS'] ||= '/opt/deployments'
25
+
26
+ class Deployer
27
+
28
+ attr_accessor :push
29
+
30
+ def initialize(push)
31
+ @push = push
32
+ end
33
+
34
+ def self.deploy(push)
35
+ push.deploy
36
+ DeployerTask.async(:deploy, :id=>push.id)
37
+ end
38
+
39
+ def self.undeploy(push, async = true)
40
+ push.undeploy
41
+ if async
42
+ DeployerTask.async(:undeploy, :id=>push.id)
43
+ else
44
+ Deployer.new(push).undeploy
45
+ end
46
+ end
47
+
48
+ def self.undeploy_branch(branch)
49
+ Deployment.all(:branch=>branch).each do |d|
50
+ Deployer.undeploy(d.push, false)
51
+ end
52
+ end
53
+
54
+ def undeploy
55
+ TorqueBox::RakeUtils.undeploy( "#{repository_name}-knob.yml" )
56
+ remove_repo if ( File.exist?( root ) )
57
+ push.undeployed
58
+ end
59
+
60
+ def deploy
61
+ begin
62
+ clone_repo
63
+ freeze_gems
64
+ write_descriptor
65
+ push.deployed
66
+ push.save
67
+ d = Deployment.create(
68
+ :created_at=>Time.now,
69
+ :push=>push,
70
+ :branch=>push.branch,
71
+ :path=>deployment_path,
72
+ :context=>"/#{repository_name}")
73
+ d.save!
74
+ rescue Exception => ex
75
+ puts ex
76
+ push.failed
77
+ end
78
+ end
79
+
80
+ # Hack to avoid problems with github responses using git gem over https
81
+ def git_url
82
+ push.repo_url.sub('https://github.com/', 'git@github.com:')
83
+ end
84
+
85
+ def deployment_path
86
+ @deployment_path ||= ENV['DEPLOYMENTS']
87
+ end
88
+
89
+ def repository_name
90
+ @repo_name ||= push.master? ? push.repo_name : "#{push.repo_name}-#{push.branch}"
91
+ end
92
+
93
+ def root
94
+ "#{deployment_path}/#{repository_name}"
95
+ end
96
+
97
+ protected
98
+
99
+ def remove_repo
100
+ puts "Removing #{repository_name}"
101
+ FileUtils.rm_rf( root )
102
+ end
103
+
104
+ def clone_repo
105
+ remove_repo if ( File.exist?( root ) )
106
+ puts "Cloning #{git_url} to #{root}"
107
+ git = Git.clone(git_url, repository_name, :path=>deployment_path)
108
+ puts "Resetting repo to #{push['after']}"
109
+ git.reset_hard(push['after'])
110
+ end
111
+
112
+ def freeze_gems
113
+ puts "Freezing gems"
114
+ jruby = File.join( RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'] )
115
+ if ( File.exist?( path_to('Gemfile') ) )
116
+ exec_cmd( "cd #{root} && #{jruby} -S bundle package" )
117
+ exec_cmd( "cd #{root} && #{jruby} -S bundle install --local --path vendor/bundle" )
118
+ else
119
+ exec_cmd( "cd #{root} && #{jruby} -S rake rails:freeze:gems" )
120
+ end
121
+ end
122
+
123
+ def write_descriptor
124
+ name, descriptor = deployment( repository_name, root, "/#{repository_name}" )
125
+ TorqueBox::RakeUtils.deploy_yaml( name, descriptor )
126
+ end
127
+
128
+ def path_to(file)
129
+ "#{root}/#{file}"
130
+ end
131
+
132
+ def exec_cmd(cmd)
133
+ Open3.popen3( cmd ) do |stdin, stdout, stderr|
134
+ stdin.close
135
+ stdout_thr = Thread.new(stdout) {|stdout_io|
136
+ stdout_io.each_line do |l|
137
+ STDOUT.puts l
138
+ STDOUT.flush
139
+ end
140
+ stdout_io.close
141
+ }
142
+ stderr_thr = Thread.new(stderr) {|stderr_io|
143
+ stderr_io.each_line do |l|
144
+ STDERR.puts l
145
+ STDERR.flush
146
+ end
147
+ }
148
+ stdout_thr.join
149
+ stderr_thr.join
150
+ end
151
+ end
152
+ end
153
+
154
+
155
+
156
+
data/app/helpers.rb ADDED
@@ -0,0 +1,59 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ module StompBox
18
+ class Application < Sinatra::Base
19
+
20
+ helpers do
21
+
22
+ def config(key)
23
+ ENV[key]
24
+ end
25
+
26
+ def home_path
27
+ request.script_name
28
+ end
29
+
30
+ def push_path
31
+ port = request.port == 80 ? "" : ":#{request.port}"
32
+ request.scheme + "://" + request.host + port + to( "push/#{config('API_KEY')}" )
33
+ end
34
+
35
+ def to(location)
36
+ location.gsub!(/^\//, '')
37
+ "#{home_path}/#{location}"
38
+ end
39
+
40
+ def repositories
41
+ @repositories ||= Repository.ordered
42
+ end
43
+
44
+ def classes_for(push)
45
+ track = push.tracked? ? 'tracked' : 'ignored'
46
+ [push.status, track, classify(push.repo_name), classify(push.branch)]
47
+ end
48
+
49
+ def selector_for(push)
50
+ classes_for(push).join('.')
51
+ end
52
+
53
+ def classify(str)
54
+ str.gsub('.', '-')
55
+ end
56
+
57
+ end
58
+ end
59
+ end
data/app/models.rb ADDED
@@ -0,0 +1,150 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'json'
18
+ require 'state_machine'
19
+ require 'dm-core'
20
+ require 'dm-migrations'
21
+ require 'dm-timestamps'
22
+
23
+ class Push
24
+ include DataMapper::Resource
25
+
26
+ property :id, Serial
27
+ property :status, String
28
+ property :payload, Text, :required => true, :lazy => false
29
+ property :created_at, DateTime
30
+
31
+ has 1, :deployment
32
+
33
+ attr_accessor :parsed_payload
34
+
35
+ state_machine :status, :initial => :received do
36
+
37
+ event :deploy do
38
+ transition all - [:deploying, :deployed] => :deploying
39
+ end
40
+
41
+ event :deployed do
42
+ transition :deploying => :deployed
43
+ end
44
+
45
+ event :failed do
46
+ transition all => :failed
47
+ end
48
+
49
+ event :undeploy do
50
+ transition :deployed => :undeploying
51
+ end
52
+
53
+ event :undeployed do
54
+ transition all => :undeployed
55
+ end
56
+
57
+ after_transition all => :undeploying do
58
+ self.deployment.destroy unless self.deployment.nil?
59
+ end
60
+
61
+ end
62
+
63
+ def tracked?
64
+ Repository.ordered.any? { |r| r.name == repo_name && r.branch == branch }
65
+ end
66
+
67
+ def [](property)
68
+ parse_payload[property]
69
+ end
70
+
71
+ def repo_url
72
+ self['repository']['url']
73
+ end
74
+
75
+ def repo_name
76
+ self['repository']['name']
77
+ end
78
+
79
+ def branch
80
+ self['ref'].split('/').last
81
+ end
82
+
83
+ def master?
84
+ branch == 'master'
85
+ end
86
+
87
+ def short_commit_hash
88
+ self['after'][0..6]
89
+ end
90
+
91
+ def self.deployed
92
+ Push.all(:status=>:deployed)
93
+ end
94
+
95
+ protected
96
+ def parse_payload
97
+ @parsed_payload ||= JSON.parse(self.payload)
98
+ end
99
+
100
+ end
101
+
102
+ class Deployment
103
+ include DataMapper::Resource
104
+
105
+ property :id, Serial
106
+ property :path, String
107
+ property :context, String
108
+ property :branch, String
109
+ property :created_at, DateTime
110
+
111
+ belongs_to :push
112
+
113
+ end
114
+
115
+ class Repository
116
+ include DataMapper::Resource
117
+
118
+ property :id, Serial
119
+ property :name, String
120
+ property :branch, String
121
+
122
+ def self.ordered
123
+ Repository.all(:order => [:name, :branch])
124
+ end
125
+
126
+ end
127
+
128
+ class DeploymentFile
129
+ include DataMapper::Resource
130
+
131
+ property :id, Serial
132
+ property :path, String
133
+ property :body, Text
134
+
135
+ belongs_to :repository
136
+
137
+ end
138
+
139
+ database_url = ENV['DATABASE_URL']
140
+ database_url ||= 'postgres://stompbox:stompbox@localhost/stompbox'
141
+
142
+ DataMapper::Logger.new($stdout, :info)
143
+ DataMapper.setup(:default, database_url)
144
+ DataMapper::Model.raise_on_save_failure = true
145
+ DataMapper.finalize
146
+
147
+
148
+ if ENV['AUTO_MIGRATE']
149
+ DataMapper.auto_upgrade!
150
+ end