freerange_deploy 0.1.1 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README +11 -12
- data/Rakefile +35 -13
- data/bin/freerange-deploy +4 -0
- data/freerange_deploy.gemspec +38 -10
- data/lib/freerange/cli/deploy.rb +27 -0
- data/lib/freerange/cli/templates/Capfile.erb +6 -0
- data/lib/freerange/cli/templates/deploy.rb.erb +19 -0
- data/lib/freerange/cli/templates/production.rb.erb +4 -0
- data/lib/freerange/cli/templates/staging.rb.erb +4 -0
- data/lib/freerange/deploy.rb +91 -30
- metadata +82 -18
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg
|
data/README
CHANGED
@@ -6,28 +6,27 @@ Allows simple, git-based deployment on freerange-compatible servers (see assumpt
|
|
6
6
|
How to use
|
7
7
|
----------
|
8
8
|
|
9
|
-
In your project,
|
9
|
+
In your project, run:
|
10
10
|
|
11
|
-
|
11
|
+
$ freerange-deploy setup REPOSITORY HOST [NAME]
|
12
12
|
|
13
|
-
|
14
|
-
set :application, "gofreerange.com" # defaults to the name of the repo at origin
|
13
|
+
This should add a Capfile, config/deploy.rb and config/deploy/production.rb files to the project. Feel free to edit the deploy.rb and production.rb files as you wish.
|
15
14
|
|
16
|
-
|
15
|
+
When ready, from your project run:
|
17
16
|
|
18
|
-
$ cap
|
19
|
-
|
20
|
-
This adds a git remote to your local repository, and creates an apache virtual host configuration on the server, and performs the initial git deploy. To deploy again, just push to 'production'
|
17
|
+
$ cap production host:setup
|
18
|
+
$ cap production deploy:setup
|
21
19
|
|
22
|
-
|
20
|
+
The first command adds a VHOST file to /etc/apache2/sites-available and enables it. The second does the standard capistrano setup stuff.
|
23
21
|
|
22
|
+
For simple apps, you should now be able to deploy:
|
24
23
|
|
24
|
+
$ cap production deploy
|
25
25
|
|
26
26
|
Assumptions
|
27
27
|
-----------
|
28
28
|
|
29
29
|
1. You're deploying as 'deploy'
|
30
30
|
2. You're deploying to /var/www/<application>
|
31
|
-
3.
|
32
|
-
4. The deploy user
|
33
|
-
5. The deploy user is a sudoer
|
31
|
+
3. The deploy user has write access to /etc/apache2/sites-available
|
32
|
+
4. The deploy user is a sudoer
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require "rubygems"
|
|
2
2
|
require "rake/gempackagetask"
|
3
3
|
require "rake/rdoctask"
|
4
4
|
|
5
|
-
|
5
|
+
path = File.expand_path("..", __FILE__)
|
6
6
|
|
7
7
|
task :default => :package do
|
8
8
|
puts "Don't forget to write some tests!"
|
@@ -16,24 +16,30 @@ end
|
|
16
16
|
spec = Gem::Specification.new do |s|
|
17
17
|
|
18
18
|
# Change these as appropriate
|
19
|
-
s.name
|
20
|
-
s.version
|
21
|
-
s.summary
|
22
|
-
s.author
|
23
|
-
s.email
|
24
|
-
s.homepage
|
25
|
-
|
19
|
+
s.name = "freerange_deploy"
|
20
|
+
s.version = "0.1.5"
|
21
|
+
s.summary = "Enables simple git-based deployments to freerange-compatible hosts"
|
22
|
+
s.author = "James Adam, Tom Ward"
|
23
|
+
s.email = "lets@gofreerange.com"
|
24
|
+
s.homepage = "http://gofreerange.com"
|
25
|
+
s.default_executable = %q{freerange-deploy}
|
26
|
+
s.executables = ["freerange-deploy"]
|
27
|
+
|
26
28
|
s.has_rdoc = true
|
27
29
|
s.extra_rdoc_files = %w(README)
|
28
30
|
s.rdoc_options = %w(--main README)
|
29
31
|
|
30
32
|
# Add any extra files to include in the gem
|
31
|
-
s.files =
|
33
|
+
s.files = `cd #{path} && git ls-files`.split("\n").sort
|
32
34
|
s.require_paths = ["lib"]
|
33
35
|
|
34
36
|
# If you want to depend on other gems, add them here, along with any
|
35
37
|
# relevant versions
|
36
|
-
s.add_dependency("
|
38
|
+
s.add_dependency("capistrano")
|
39
|
+
s.add_dependency("capistrano-ext")
|
40
|
+
s.add_dependency("thor")
|
41
|
+
s.add_dependency("tinder")
|
42
|
+
s.add_dependency("json")
|
37
43
|
|
38
44
|
# If your tests use any gems, include them here
|
39
45
|
# s.add_development_dependency("mocha") # for example
|
@@ -48,12 +54,28 @@ end
|
|
48
54
|
# about that here: http://gemcutter.org/pages/gem_docs
|
49
55
|
Rake::GemPackageTask.new(spec) do |pkg|
|
50
56
|
pkg.gem_spec = spec
|
57
|
+
end
|
51
58
|
|
52
|
-
|
53
|
-
|
54
|
-
|
59
|
+
# Stolen from jeweler
|
60
|
+
def prettyify_array(gemspec_ruby, array_name)
|
61
|
+
gemspec_ruby.gsub(/s\.#{array_name.to_s} = \[.+?\]/) do |match|
|
62
|
+
leadin, files = match[0..-2].split("[")
|
63
|
+
leadin + "[\n #{files.split(",").join(",\n ")}\n ]"
|
64
|
+
end
|
55
65
|
end
|
56
66
|
|
67
|
+
task :gemspec do
|
68
|
+
output = spec.to_ruby
|
69
|
+
output = prettyify_array(output, :files)
|
70
|
+
output = prettyify_array(output, :test_files)
|
71
|
+
output = prettyify_array(output, :extra_rdoc_files)
|
72
|
+
|
73
|
+
file = File.expand_path("../#{spec.name}.gemspec", __FILE__)
|
74
|
+
File.open(file, "w") {|f| f << output }
|
75
|
+
end
|
76
|
+
|
77
|
+
task :package => :gemspec
|
78
|
+
|
57
79
|
# Generate documentation
|
58
80
|
Rake::RDocTask.new do |rd|
|
59
81
|
rd.main = "README"
|
data/freerange_deploy.gemspec
CHANGED
@@ -2,18 +2,34 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{freerange_deploy}
|
5
|
-
s.version = "0.1.
|
5
|
+
s.version = "0.1.4"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
-
s.authors = ["James Adam"]
|
9
|
-
s.date = %q{2010-
|
10
|
-
s.
|
11
|
-
s.
|
12
|
-
s.
|
8
|
+
s.authors = ["James Adam, Tom Ward"]
|
9
|
+
s.date = %q{2010-04-07}
|
10
|
+
s.default_executable = %q{freerange-deploy}
|
11
|
+
s.email = %q{lets@gofreerange.com}
|
12
|
+
s.executables = ["freerange-deploy"]
|
13
|
+
s.extra_rdoc_files = [
|
14
|
+
"README"
|
15
|
+
]
|
16
|
+
s.files = [
|
17
|
+
".gitignore",
|
18
|
+
"README",
|
19
|
+
"Rakefile",
|
20
|
+
"bin/freerange-deploy",
|
21
|
+
"freerange_deploy.gemspec",
|
22
|
+
"lib/freerange/cli/deploy.rb",
|
23
|
+
"lib/freerange/cli/templates/Capfile.erb",
|
24
|
+
"lib/freerange/cli/templates/deploy.rb.erb",
|
25
|
+
"lib/freerange/cli/templates/production.rb.erb",
|
26
|
+
"lib/freerange/cli/templates/staging.rb.erb",
|
27
|
+
"lib/freerange/deploy.rb"
|
28
|
+
]
|
13
29
|
s.homepage = %q{http://gofreerange.com}
|
14
30
|
s.rdoc_options = ["--main", "README"]
|
15
31
|
s.require_paths = ["lib"]
|
16
|
-
s.rubygems_version = %q{1.3.
|
32
|
+
s.rubygems_version = %q{1.3.6}
|
17
33
|
s.summary = %q{Enables simple git-based deployments to freerange-compatible hosts}
|
18
34
|
|
19
35
|
if s.respond_to? :specification_version then
|
@@ -21,11 +37,23 @@ Gem::Specification.new do |s|
|
|
21
37
|
s.specification_version = 3
|
22
38
|
|
23
39
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
24
|
-
s.add_runtime_dependency(%q<
|
40
|
+
s.add_runtime_dependency(%q<capistrano>, [">= 0"])
|
41
|
+
s.add_runtime_dependency(%q<capistrano-ext>, [">= 0"])
|
42
|
+
s.add_runtime_dependency(%q<thor>, [">= 0"])
|
43
|
+
s.add_runtime_dependency(%q<tinder>, [">= 0"])
|
44
|
+
s.add_runtime_dependency(%q<json>, [">= 0"])
|
25
45
|
else
|
26
|
-
s.add_dependency(%q<
|
46
|
+
s.add_dependency(%q<capistrano>, [">= 0"])
|
47
|
+
s.add_dependency(%q<capistrano-ext>, [">= 0"])
|
48
|
+
s.add_dependency(%q<thor>, [">= 0"])
|
49
|
+
s.add_dependency(%q<tinder>, [">= 0"])
|
50
|
+
s.add_dependency(%q<json>, [">= 0"])
|
27
51
|
end
|
28
52
|
else
|
29
|
-
s.add_dependency(%q<
|
53
|
+
s.add_dependency(%q<capistrano>, [">= 0"])
|
54
|
+
s.add_dependency(%q<capistrano-ext>, [">= 0"])
|
55
|
+
s.add_dependency(%q<thor>, [">= 0"])
|
56
|
+
s.add_dependency(%q<tinder>, [">= 0"])
|
57
|
+
s.add_dependency(%q<json>, [">= 0"])
|
30
58
|
end
|
31
59
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'thor'
|
3
|
+
|
4
|
+
module FreeRange
|
5
|
+
module CLI
|
6
|
+
class Deploy < Thor
|
7
|
+
include Thor::Actions
|
8
|
+
|
9
|
+
def self.source_root
|
10
|
+
File.expand_path("../templates", __FILE__)
|
11
|
+
end
|
12
|
+
|
13
|
+
argument :repository, :required => true, :desc => 'Git repository containing app, e.g. git@github.com:freerange/deploy.git'
|
14
|
+
argument :host, :required => true, :desc => 'Hostname to deploy to, e.g api.hashblue.com'
|
15
|
+
argument :name, :required => false, :desc => 'Name of app, e.g firehose'
|
16
|
+
|
17
|
+
desc 'setup', 'Setup freerange deployment files, eg freerange-deploy setup git@github.com:freerange/o2-firehose.git api.firehose.com firehose'
|
18
|
+
def setup
|
19
|
+
self.name ||= host
|
20
|
+
template 'Capfile.erb', 'Capfile'
|
21
|
+
template 'deploy.rb.erb', 'config/deploy.rb'
|
22
|
+
template 'staging.rb.erb', 'config/deploy/staging.rb'
|
23
|
+
template 'production.rb.erb', 'config/deploy/production.rb'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
set :stages, %w(staging production)
|
2
|
+
set :default_stage, "production"
|
3
|
+
|
4
|
+
require 'freerange/deploy'
|
5
|
+
|
6
|
+
set :application, "<%= name %>"
|
7
|
+
set :repository, "<%= repository %>"
|
8
|
+
|
9
|
+
# Set the following to announce releases in campfire rooms
|
10
|
+
|
11
|
+
# set :campfire_domain, "subdomain"
|
12
|
+
# set :campfire_room, "room-name"
|
13
|
+
# set :campfire_key, "abcdef1234567890"
|
14
|
+
|
15
|
+
after "deploy:finalize_update" do
|
16
|
+
# The default recipe already runs bundler install and db:migrate
|
17
|
+
# but other steps you need to run after the code has been updated
|
18
|
+
# (such as generate css) should go here
|
19
|
+
end
|
data/lib/freerange/deploy.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'capistrano/ext/multistage'
|
2
2
|
|
3
3
|
Capistrano::Configuration.instance(:must_exist).load do
|
4
4
|
# User details
|
@@ -11,50 +11,111 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
11
11
|
|
12
12
|
# SCM settings
|
13
13
|
set :scm, 'git'
|
14
|
-
|
15
|
-
set :remote, 'production' # overrides the default git-deploy setting of 'origin'
|
16
|
-
# specify the deployment branch
|
17
|
-
set :branch, 'master'
|
14
|
+
set :deploy_via, :remote_cache
|
18
15
|
|
19
|
-
# The appliation name defaults to the name of the repository at the origin remote
|
20
|
-
set(:application) { File.basename(`#{source.local.scm('config', "remote.origin.url")}`, ".git") }
|
21
|
-
|
22
16
|
# Deploy to our default location
|
23
17
|
set(:deploy_to) { "/var/www/#{application}" }
|
18
|
+
set(:sites) { }
|
24
19
|
|
25
20
|
# Git settings for Capistrano
|
26
21
|
default_run_options[:pty] = true # needed for git password prompts
|
27
22
|
ssh_options[:forward_agent] = true # use the keys for the person running the cap command to check out the app
|
28
23
|
|
29
|
-
|
30
|
-
|
31
|
-
after "deploy:setup", "freerange:setup_apache"
|
32
|
-
|
33
|
-
namespace "freerange" do
|
34
|
-
task :setup_git_remote do
|
35
|
-
remote_url = "deploy@#{roles[:app].first}:/var/www/#{application}"
|
36
|
-
puts "Setting up git remote '#{remote}' -> #{remote_url}"
|
37
|
-
`git remote add #{remote} #{remote_url}`
|
38
|
-
end
|
39
|
-
task :setup_apache do
|
24
|
+
namespace :host do
|
25
|
+
task :create do
|
40
26
|
vhost_template =<<-EOT
|
41
27
|
<VirtualHost *:80>
|
42
|
-
|
43
|
-
|
44
|
-
<Directory "/var/www/#{application}/public">
|
28
|
+
ServerName #{domain}
|
29
|
+
DocumentRoot /var/www/#{application}/current/public
|
30
|
+
<Directory "/var/www/#{application}/current/public">
|
45
31
|
allow from all
|
46
32
|
Options +Indexes
|
47
|
-
|
33
|
+
</Directory>
|
48
34
|
</VirtualHost>
|
49
35
|
EOT
|
50
|
-
|
51
|
-
put vhost_template.strip, "/var/www/apache_vhosts/#{application}"
|
52
|
-
|
53
|
-
# Disable the default site, just in case; it will get in the way.
|
54
|
-
sudo "a2dissite default"
|
55
36
|
|
56
|
-
|
57
|
-
|
37
|
+
put vhost_template.strip, "/etc/apache2/sites-available/#{domain}"
|
38
|
+
end
|
39
|
+
|
40
|
+
task :enable do
|
41
|
+
run "a2ensite #{domain}"
|
42
|
+
sudo "apache2ctl graceful"
|
43
|
+
end
|
44
|
+
|
45
|
+
task :disable do
|
46
|
+
run "a2dissite #{domain}"
|
47
|
+
sudo "apache2ctl graceful"
|
48
|
+
end
|
49
|
+
|
50
|
+
task :setup do
|
51
|
+
host.create
|
52
|
+
host.enable
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# We're using passenger, so start/stop don't apply, while restart needs to just
|
57
|
+
# touch path/restart.txt
|
58
|
+
|
59
|
+
namespace :deploy do
|
60
|
+
task :start do ; end
|
61
|
+
task :stop do ; end
|
62
|
+
task :restart, :roles => :app, :except => { :no_release => true } do
|
63
|
+
run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
|
64
|
+
end
|
65
|
+
|
66
|
+
task :bundle, :roles => :app do
|
67
|
+
run "cd #{release_path} && bundle install"
|
68
|
+
end
|
69
|
+
|
70
|
+
task :announce do
|
71
|
+
if room = fetch('campfire_room', nil)
|
72
|
+
require 'tinder'
|
73
|
+
require 'json'
|
74
|
+
campfire = Tinder::Campfire.new(fetch('campfire_domain', 'gofreerange'))
|
75
|
+
campfire.login(fetch('campfire_key'), 'x')
|
76
|
+
room = campfire.find_room_by_name(room)
|
77
|
+
|
78
|
+
name = `git config --get user.name`.strip
|
79
|
+
|
80
|
+
source_repo_url = repository
|
81
|
+
deploying = `git rev-parse HEAD`[0,7]
|
82
|
+
begin
|
83
|
+
deployed = previous_revision[0,7]
|
84
|
+
rescue
|
85
|
+
deployed = "000000"
|
86
|
+
end
|
87
|
+
|
88
|
+
github_url = repository.gsub(/git@/, 'http://').gsub(/\.com:/,'.com/').gsub(/\.git/, '')
|
89
|
+
compare_url = "#{github_url}/compare/#{deployed}...#{deploying}"
|
90
|
+
|
91
|
+
hosts = roles[:app].collect{|r| r.host }.join(", ")
|
92
|
+
|
93
|
+
room.speak "#{name} has deployed build #{deployed} of #{application} to #{hosts}"
|
94
|
+
room.speak "Changes: #{compare_url}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
after "deploy:finalize_update" do
|
100
|
+
deploy.bundle
|
101
|
+
deploy.migrate
|
102
|
+
end
|
103
|
+
|
104
|
+
after "deploy:restart" do
|
105
|
+
deploy.announce
|
106
|
+
end
|
107
|
+
|
108
|
+
desc "Tail server log files"
|
109
|
+
task :tail, :roles => :app do
|
110
|
+
trap("INT") { exit(0) }
|
111
|
+
puts
|
112
|
+
puts "Checking server time"
|
113
|
+
run "date"
|
114
|
+
puts
|
115
|
+
run "tail -f #{shared_path}/log/#{stage}.log" do |channel, stream, data|
|
116
|
+
puts # for an extra line break before the host name
|
117
|
+
puts "#{channel[:host]}: #{data}"
|
118
|
+
break if stream == :err
|
58
119
|
end
|
59
120
|
end
|
60
121
|
end
|
metadata
CHANGED
@@ -1,39 +1,101 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: freerange_deploy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 5
|
9
|
+
version: 0.1.5
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
|
-
- James Adam
|
12
|
+
- James Adam, Tom Ward
|
8
13
|
autorequire:
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-
|
13
|
-
default_executable:
|
17
|
+
date: 2010-04-14 00:00:00 +01:00
|
18
|
+
default_executable: freerange-deploy
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
21
|
+
name: capistrano
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: capistrano-ext
|
34
|
+
prerelease: false
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 0
|
41
|
+
version: "0"
|
17
42
|
type: :runtime
|
18
|
-
|
19
|
-
|
43
|
+
version_requirements: *id002
|
44
|
+
- !ruby/object:Gem::Dependency
|
45
|
+
name: thor
|
46
|
+
prerelease: false
|
47
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
segments:
|
52
|
+
- 0
|
53
|
+
version: "0"
|
54
|
+
type: :runtime
|
55
|
+
version_requirements: *id003
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: tinder
|
58
|
+
prerelease: false
|
59
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
20
60
|
requirements:
|
21
|
-
- -
|
61
|
+
- - ">="
|
22
62
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
version: "0"
|
66
|
+
type: :runtime
|
67
|
+
version_requirements: *id004
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: json
|
70
|
+
prerelease: false
|
71
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
type: :runtime
|
79
|
+
version_requirements: *id005
|
25
80
|
description:
|
26
|
-
email:
|
27
|
-
executables:
|
28
|
-
|
81
|
+
email: lets@gofreerange.com
|
82
|
+
executables:
|
83
|
+
- freerange-deploy
|
29
84
|
extensions: []
|
30
85
|
|
31
86
|
extra_rdoc_files:
|
32
87
|
- README
|
33
88
|
files:
|
34
|
-
-
|
35
|
-
- Rakefile
|
89
|
+
- .gitignore
|
36
90
|
- README
|
91
|
+
- Rakefile
|
92
|
+
- bin/freerange-deploy
|
93
|
+
- freerange_deploy.gemspec
|
94
|
+
- lib/freerange/cli/deploy.rb
|
95
|
+
- lib/freerange/cli/templates/Capfile.erb
|
96
|
+
- lib/freerange/cli/templates/deploy.rb.erb
|
97
|
+
- lib/freerange/cli/templates/production.rb.erb
|
98
|
+
- lib/freerange/cli/templates/staging.rb.erb
|
37
99
|
- lib/freerange/deploy.rb
|
38
100
|
has_rdoc: true
|
39
101
|
homepage: http://gofreerange.com
|
@@ -49,18 +111,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
49
111
|
requirements:
|
50
112
|
- - ">="
|
51
113
|
- !ruby/object:Gem::Version
|
114
|
+
segments:
|
115
|
+
- 0
|
52
116
|
version: "0"
|
53
|
-
version:
|
54
117
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
118
|
requirements:
|
56
119
|
- - ">="
|
57
120
|
- !ruby/object:Gem::Version
|
121
|
+
segments:
|
122
|
+
- 0
|
58
123
|
version: "0"
|
59
|
-
version:
|
60
124
|
requirements: []
|
61
125
|
|
62
126
|
rubyforge_project:
|
63
|
-
rubygems_version: 1.3.
|
127
|
+
rubygems_version: 1.3.6
|
64
128
|
signing_key:
|
65
129
|
specification_version: 3
|
66
130
|
summary: Enables simple git-based deployments to freerange-compatible hosts
|