moode_auto_deploy_kit 0.0.1
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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +40 -0
- data/Rakefile +1 -0
- data/bin/deploy_kit +67 -0
- data/deploy_config.rb +75 -0
- data/deploy_scripts/configs/deploy_config.json +43 -0
- data/deploy_scripts/gemfiles/server_gemfile +3 -0
- data/deploy_scripts/templates/app/assets/www/.rvmrc +2 -0
- data/deploy_scripts/templates/app/deploy.sh +11 -0
- data/deploy_scripts/templates/deploy.sh +37 -0
- data/deploy_scripts/templates/scripts/common/common.sh +3 -0
- data/deploy_scripts/templates/scripts/common/dir_structure.sh +28 -0
- data/deploy_scripts/templates/scripts/common/infra.sh +26 -0
- data/deploy_scripts/templates/scripts/config.sh +5 -0
- data/deploy_scripts/templates/scripts/deploy/deploy.sh +20 -0
- data/deploy_scripts/templates/scripts/deploy/post_deployment.sh +4 -0
- data/deploy_scripts/templates/scripts/deploy/pre_deployment.sh +4 -0
- data/deploy_scripts/templates/server/.rvmrc +2 -0
- data/deploy_scripts/templates/server/Capfile +33 -0
- data/deploy_scripts/templates/server/config/database.yml +29 -0
- data/deploy_scripts/templates/server/config/deploy.rb +60 -0
- data/deploy_scripts/templates/server/deploy.sh +3 -0
- data/lib/moode_auto_deploy_kit/infra/utils.rb +56 -0
- data/lib/moode_auto_deploy_kit/remote.rb +25 -0
- data/lib/moode_auto_deploy_kit/remote_domain.rb +24 -0
- data/lib/moode_auto_deploy_kit/remote_job.rb +24 -0
- data/lib/moode_auto_deploy_kit/script_provider.rb +63 -0
- data/lib/moode_auto_deploy_kit/version.rb +3 -0
- data/lib/moode_auto_deploy_kit.rb +7 -0
- data/moode_auto_deploy_kit.gemspec +26 -0
- metadata +149 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2013 lishoubo
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# MoodeAutoDeployKit
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## Installation
|
|
5
|
+
|
|
6
|
+
Add this line to your application's Gemfile:
|
|
7
|
+
|
|
8
|
+
gem 'moode_auto_deploy_kit'
|
|
9
|
+
|
|
10
|
+
And then execute:
|
|
11
|
+
|
|
12
|
+
$ bundle
|
|
13
|
+
|
|
14
|
+
Or install it yourself as:
|
|
15
|
+
|
|
16
|
+
$ gem install moode_auto_deploy_kit
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Add deploy scripts to current project:
|
|
22
|
+
|
|
23
|
+
$ deploy_kit configure
|
|
24
|
+
|
|
25
|
+
After fill in the configuration, you can create a new jenkin job:
|
|
26
|
+
|
|
27
|
+
$ deploy_kit new_job
|
|
28
|
+
|
|
29
|
+
create a new domain:
|
|
30
|
+
|
|
31
|
+
$ deploy_kit new_domain
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## Contributing
|
|
35
|
+
|
|
36
|
+
1. Fork it
|
|
37
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
38
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
39
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
40
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/deploy_kit
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require "thor"
|
|
3
|
+
require "ostruct"
|
|
4
|
+
require "fileutils"
|
|
5
|
+
|
|
6
|
+
require File.expand_path("../../lib/moode_auto_deploy_kit", __FILE__)
|
|
7
|
+
require File.expand_path("../../deploy_config", __FILE__)
|
|
8
|
+
|
|
9
|
+
$fs = OpenStruct.new
|
|
10
|
+
|
|
11
|
+
$fs.root = File.expand_path("../../", __FILE__)
|
|
12
|
+
$fs.deploy_scripts = File.join($fs.root, 'deploy_scripts')
|
|
13
|
+
$fs.deploy_script_template_dir = File.join($fs.deploy_scripts, 'templates')
|
|
14
|
+
|
|
15
|
+
$fs.gemfiles = File.join($fs.deploy_scripts, 'gemfiles')
|
|
16
|
+
$fs.server_gemfile = File.join($fs.gemfiles, 'server_gemfile')
|
|
17
|
+
|
|
18
|
+
$fs.configs = File.join($fs.deploy_scripts, 'configs')
|
|
19
|
+
$fs.deploy_config_file = File.join($fs.configs, 'deploy_config.json')
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DeployKit < Thor
|
|
23
|
+
|
|
24
|
+
include MoodeAutoDeployKit::ScriptProvider
|
|
25
|
+
include MoodeAutoDeployKit::RemoteJob
|
|
26
|
+
include MoodeAutoDeployKit::RemoteDomain
|
|
27
|
+
|
|
28
|
+
desc "apply", "apply deploy scripts to current project"
|
|
29
|
+
def apply(app_dir = ".", config_file = "deploy_config.json")
|
|
30
|
+
app_path = File.join(FileUtils.pwd(), app_dir)
|
|
31
|
+
config_working_dir_to_app(app_path)
|
|
32
|
+
read_config File.join(app_path, config_file)
|
|
33
|
+
create_script app_path
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
desc "configure", "generate config template"
|
|
37
|
+
def configure
|
|
38
|
+
FileUtils.cp $fs.deploy_config_file, FileUtils.pwd()
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
desc "new_job", "create a jenkins job for project"
|
|
42
|
+
def new_job(config_file = "deploy_config.json")
|
|
43
|
+
config_file_path = File.join(FileUtils.pwd(), config_file)
|
|
44
|
+
read_config config_file_path
|
|
45
|
+
create_job
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
desc "new_domain", "create a domain for project"
|
|
49
|
+
def new_domain(config_file = "deploy_config.json")
|
|
50
|
+
config_file_path = File.join(FileUtils.pwd(), config_file)
|
|
51
|
+
read_config config_file_path
|
|
52
|
+
create_domain
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def config_working_dir_to_app(app_path)
|
|
58
|
+
$fs.working = File.join(app_path, "working")
|
|
59
|
+
$fs.deploy_script_working_dir = File.join($fs.working, 'deploy_scripts')
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def read_config(deploy_config_file)
|
|
63
|
+
$config = DeployConfig.new(deploy_config_file)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
DeployKit.start
|
data/deploy_config.rb
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require "logger"
|
|
3
|
+
|
|
4
|
+
class DeployConfig
|
|
5
|
+
def initialize(config_file)
|
|
6
|
+
read_config config_file
|
|
7
|
+
verify_config
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def each_pair(&block)
|
|
11
|
+
raise "Should call with a block" unless block_given?
|
|
12
|
+
@config.each_pair do |key, value|
|
|
13
|
+
block.call(key, value)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_s
|
|
18
|
+
@config.collect {|pair| "#{pair.first} => #{pair.last}"}.join("\n")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def get_binding
|
|
22
|
+
each_pair do |key, value|
|
|
23
|
+
instance_variable_set "@#{key}", value
|
|
24
|
+
end
|
|
25
|
+
binding
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def [](key)
|
|
29
|
+
raise "Unknown configuration item #{key}" unless @config.has_key? key
|
|
30
|
+
@config[key]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def []=(key, value)
|
|
34
|
+
@config[key] = value
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def verify_config
|
|
40
|
+
assert_no_empty_config_items
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def assert_no_empty_config_items
|
|
44
|
+
nullable_items = allow_null_items.split(",")
|
|
45
|
+
empty_config_items = @config.select { |key| @config[key].empty? && !nullable_items.include?(key)}
|
|
46
|
+
unless empty_config_items.empty?
|
|
47
|
+
Process.abort "Configuration items should not be empty: #{empty_config_items.keys.join(",")}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def allow_null_items
|
|
52
|
+
@config["_nullable_items"] || ""
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def log(message)
|
|
56
|
+
@logger ||= Logger.new(STDOUT)
|
|
57
|
+
@logger.info message
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def read_config(config_file)
|
|
61
|
+
@config = parse_config config_file
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def parse_config(config_file)
|
|
65
|
+
content = IO.readlines(config_file).join("")
|
|
66
|
+
content = "{}" if content.empty?
|
|
67
|
+
JSON.parse(content)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def method_missing(method, *args, &block)
|
|
71
|
+
key = method.to_s
|
|
72
|
+
raise "Unknown configuration item: #{method}" unless @config.has_key?(key)
|
|
73
|
+
@config[key]
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
// The name of your application, only use 'A-Za-z_0-9'
|
|
3
|
+
// such as 'sms_client'.
|
|
4
|
+
"app_name" : "",
|
|
5
|
+
|
|
6
|
+
// The IP or domain name of your app server
|
|
7
|
+
// Currently, we only support all-on-one deployment
|
|
8
|
+
// Such as '10.0.0.17'
|
|
9
|
+
"app_server" : "",
|
|
10
|
+
|
|
11
|
+
"dns_name" : "sms_client.kuaijie.com",
|
|
12
|
+
|
|
13
|
+
"job_name" : "",
|
|
14
|
+
|
|
15
|
+
// The repository url and branch
|
|
16
|
+
"repository_url" : "",
|
|
17
|
+
"repository_branch_remote" : "origin/master",
|
|
18
|
+
|
|
19
|
+
// The database information of you application
|
|
20
|
+
// Such as 'fos_db'
|
|
21
|
+
"db_name" : "",
|
|
22
|
+
"db_user_name" : "",
|
|
23
|
+
"db_user_password" : "",
|
|
24
|
+
"db_host" : "localhost",
|
|
25
|
+
"db_source_host" : "localhost",
|
|
26
|
+
"db_admin_user" : "root",
|
|
27
|
+
"db_admin_password" : "fos_db_boss",
|
|
28
|
+
|
|
29
|
+
// The server user name and key that can be used for SSH'
|
|
30
|
+
// do not need change the key
|
|
31
|
+
"app_server_user_name" : "ubuntu",
|
|
32
|
+
"app_server_user_key" : "~/.ssh/moodeci/moodeci.pem",
|
|
33
|
+
|
|
34
|
+
// The server user name and
|
|
35
|
+
// group that capistrano use to deploy
|
|
36
|
+
"app_deployer_user_name" : "ubuntu",
|
|
37
|
+
"app_deployer_user_group" : "ubuntu",
|
|
38
|
+
|
|
39
|
+
// The host used to create job and domain for user
|
|
40
|
+
"deployer_host" : "http://deployerkit.kuaijie.com",
|
|
41
|
+
|
|
42
|
+
"rvm_ruby_version" : "ruby-1.9.3-p286"
|
|
43
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
[ -s "$HOME/.rvm/scripts/rvm" ] && . "$HOME/.rvm/scripts/rvm"
|
|
4
|
+
rvm rvmrc load $APP_WWW_RVMRC
|
|
5
|
+
cd $APP_WWW_DIR
|
|
6
|
+
bundle install && mdk
|
|
7
|
+
cd $APP_DIR
|
|
8
|
+
|
|
9
|
+
ssh -i $APP_SERVER_USER_KEY $APP_SERVER_USER_NAME@$APP_SERVER "rm -fr $APP_DIR_APP_SERVER"
|
|
10
|
+
scp -i $APP_SERVER_USER_KEY -r $APP_DIR $APP_SERVER_USER_NAME@$APP_SERVER:$APP_DIR_APP_SERVER
|
|
11
|
+
ssh -i $APP_SERVER_USER_KEY $APP_SERVER_USER_NAME@$APP_SERVER "[[ -s \"$HOME/.rvm/scripts/rvm\" ]] && source \"$HOME/.rvm/scripts/rvm\" && bundle install --gemfile $APP_GEMFILE_APP_SERVER"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
|
|
4
|
+
|
|
5
|
+
CURRENT_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
6
|
+
. $CURRENT_SCRIPT_DIR/scripts/config.sh
|
|
7
|
+
. $CURRENT_SCRIPT_DIR/scripts/common/common.sh
|
|
8
|
+
|
|
9
|
+
function pre_deploy {
|
|
10
|
+
exec_script $PRE_DEPLOYMENT_SCRIPT 'pre-deployment operations'
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function post_deploy {
|
|
14
|
+
exec_script $POST_DEPLOYMENT_SCRIPT 'post-deployment operations'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function deploy {
|
|
18
|
+
exec_script $DEPLOYMENT_SCRIPT 'deployment operations'
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function clean_known_host {
|
|
22
|
+
log 'clean ~/.ssh/known_hosts'
|
|
23
|
+
cat /dev/null > ~/.ssh/known_hosts
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function main {
|
|
27
|
+
clean_known_host
|
|
28
|
+
log 'Start deployment'
|
|
29
|
+
|
|
30
|
+
pre_deploy && \
|
|
31
|
+
deploy && \
|
|
32
|
+
post_deploy &&
|
|
33
|
+
|
|
34
|
+
log 'Deployment is done'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
main
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
CURRENT_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
2
|
+
export ROOT_DIR=$CURRENT_SCRIPT_DIR/../..
|
|
3
|
+
export SCRIPTS_DIR=$ROOT_DIR/scripts
|
|
4
|
+
|
|
5
|
+
export DEPLOYMENT_SCRIPTS_DIR=$SCRIPTS_DIR/deploy
|
|
6
|
+
export PRE_DEPLOYMENT_SCRIPT=$DEPLOYMENT_SCRIPTS_DIR/pre_deployment.sh
|
|
7
|
+
export DEPLOYMENT_SCRIPT=$DEPLOYMENT_SCRIPTS_DIR/deploy.sh
|
|
8
|
+
export POST_DEPLOYMENT_SCRIPT=$DEPLOYMENT_SCRIPTS_DIR/post_deployment.sh
|
|
9
|
+
|
|
10
|
+
export SERVER_DIR=$ROOT_DIR/server
|
|
11
|
+
export SERVER_DEPLOYMENT_SCRIPT=$SERVER_DIR/deploy.sh
|
|
12
|
+
export SERVER_RVMRC=$SERVER_DIR/.rvmrc
|
|
13
|
+
|
|
14
|
+
export APP_DIR_NAME=app
|
|
15
|
+
export APP_DIR=$ROOT_DIR/$APP_DIR_NAME
|
|
16
|
+
export APP_DEPLOYMENT_SCRIPT=$APP_DIR/deploy.sh
|
|
17
|
+
export APP_WWW_DIR=$APP_DIR/assets/www
|
|
18
|
+
export APP_WWW_RVMRC=$APP_WWW_DIR/.rvmrc
|
|
19
|
+
|
|
20
|
+
export ACCEPTANCE_TEST_DIR=$ROOT_DIR/app_acceptance_test
|
|
21
|
+
export ACCEPTANCE_TEST_SCRIPT=$ACCEPTANCE_TEST_DIR/at.sh
|
|
22
|
+
|
|
23
|
+
# remote directory structure
|
|
24
|
+
export ROOT_DIR_APP_SERVER=/home/$APP_SERVER_USER_NAME
|
|
25
|
+
export DEPLOYMENT_DIR_NAME=auto_deployment
|
|
26
|
+
export DEPLOYMENT_DIR_APP_SERVER=$ROOT_DIR_APP_SERVER/$DEPLOYMENT_DIR_NAME
|
|
27
|
+
export APP_DIR_APP_SERVER=$DEPLOYMENT_DIR_APP_SERVER/releases/$APP_DIR_NAME
|
|
28
|
+
export APP_GEMFILE_APP_SERVER=$APP_DIR_APP_SERVER/assets/www/Gemfile
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
function log {
|
|
2
|
+
echo "***** $1"
|
|
3
|
+
echo ""
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function exec_script() {
|
|
7
|
+
local script=$1
|
|
8
|
+
local desc=$2
|
|
9
|
+
|
|
10
|
+
if [ -x $script ]
|
|
11
|
+
then
|
|
12
|
+
log "Will run $script which is $desc"
|
|
13
|
+
eval $script
|
|
14
|
+
if [ $? != 0 ]
|
|
15
|
+
then
|
|
16
|
+
log "Failed to run script $script"
|
|
17
|
+
exit -1
|
|
18
|
+
fi
|
|
19
|
+
else
|
|
20
|
+
log "No such script $script found or its not executable"
|
|
21
|
+
exit -1
|
|
22
|
+
fi
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
typeset -fx log
|
|
26
|
+
typeset -fx exec_script
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
[ -s "$HOME/.rvm/scripts/rvm" ] && . "$HOME/.rvm/scripts/rvm"
|
|
4
|
+
|
|
5
|
+
log 'Start deployment operations'
|
|
6
|
+
|
|
7
|
+
log 'Start server deployment operations'
|
|
8
|
+
rvm rvmrc load $SERVER_RVMRC
|
|
9
|
+
cd $SERVER_DIR
|
|
10
|
+
exec_script $SERVER_DEPLOYMENT_SCRIPT 'deployment script of server'
|
|
11
|
+
cd $ROOT_DIR
|
|
12
|
+
log 'End server deployment operations'
|
|
13
|
+
|
|
14
|
+
log 'Start app deployment operations'
|
|
15
|
+
cd $APP_DIR
|
|
16
|
+
exec_script $APP_DEPLOYMENT_SCRIPT 'deployment script of app'
|
|
17
|
+
cd $ROOT_DIR
|
|
18
|
+
log 'End app deployment operations'
|
|
19
|
+
|
|
20
|
+
log 'End deployment operations'
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
load 'deploy'
|
|
2
|
+
|
|
3
|
+
require 'capistrano/recipes/deploy/strategy/remote_cache'
|
|
4
|
+
|
|
5
|
+
class RemoteCacheSubdir < Capistrano::Deploy::Strategy::RemoteCache
|
|
6
|
+
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def repository_cache_subdir
|
|
10
|
+
if configuration[:deploy_subdir] then
|
|
11
|
+
File.join(repository_cache, configuration[:deploy_subdir])
|
|
12
|
+
else
|
|
13
|
+
repository_cache
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def copy_repository_cache
|
|
18
|
+
logger.trace "copying the cached version to #{configuration[:release_path]}"
|
|
19
|
+
if copy_exclude.empty?
|
|
20
|
+
run "cp -RPp #{repository_cache_subdir} #{configuration[:release_path]} && #{mark}"
|
|
21
|
+
else
|
|
22
|
+
exclusions = copy_exclude.map { |e| "--exclude=\"#{e}\"" }.join(' ')
|
|
23
|
+
run "rsync -lrpt #{exclusions} #{repository_cache_subdir}/* #{configuration[:release_path]} && #{mark}"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# do not use this strategy, because we use scm :none. The none SCM recipy do not implement rsync
|
|
30
|
+
# set :strategy, RemoteCacheSubdir.new(self)
|
|
31
|
+
|
|
32
|
+
load 'deploy/assets'
|
|
33
|
+
load 'config/deploy'
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# SQLite version 3.x
|
|
2
|
+
# gem install sqlite3
|
|
3
|
+
#
|
|
4
|
+
# Ensure the SQLite 3 gem is defined in your Gemfile
|
|
5
|
+
# gem 'sqlite3'
|
|
6
|
+
development:
|
|
7
|
+
adapter: sqlite3
|
|
8
|
+
database: db/development.sqlite3
|
|
9
|
+
pool: 5
|
|
10
|
+
timeout: 5000
|
|
11
|
+
|
|
12
|
+
# Warning: The database defined as "test" will be erased and
|
|
13
|
+
# re-generated from your development database when you run "rake".
|
|
14
|
+
# Do not set this db to the same as development or production.
|
|
15
|
+
test:
|
|
16
|
+
adapter: sqlite3
|
|
17
|
+
database: db/test.sqlite3
|
|
18
|
+
pool: 5
|
|
19
|
+
timeout: 5000
|
|
20
|
+
|
|
21
|
+
production:
|
|
22
|
+
adapter: mysql2
|
|
23
|
+
encoding: utf8
|
|
24
|
+
reconnect: false
|
|
25
|
+
database: <%= @db_name %>
|
|
26
|
+
pool: 5
|
|
27
|
+
username: <%= @db_user_name %>
|
|
28
|
+
password: <%= @db_user_password %>
|
|
29
|
+
host: <%= @db_host %>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
set :rvm_ruby_string, ENV['GEM_HOME'].gsub(/.*\//,"")
|
|
2
|
+
set :rvm_type, :user
|
|
3
|
+
require 'rvm/capistrano'
|
|
4
|
+
require 'bundler/capistrano'
|
|
5
|
+
|
|
6
|
+
set :application, "<%= @app_name %>"
|
|
7
|
+
|
|
8
|
+
set :repository, "."
|
|
9
|
+
set :scm, :none
|
|
10
|
+
set :deploy_via, :copy
|
|
11
|
+
|
|
12
|
+
# do not use copy cache, because we use scm :none. The none SCM recipy do not implement rsync
|
|
13
|
+
#set :copy_cache, true
|
|
14
|
+
|
|
15
|
+
set :copy_compression, :gzip
|
|
16
|
+
set :copy_exclude, ".git/*"
|
|
17
|
+
set :copy_dir, "~/tmp"
|
|
18
|
+
set :remote_copy_dir, "/tmp"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
server "<%= @app_server %>", :web, :app, :db, :primary => true
|
|
22
|
+
ssh_options[:port] = 22
|
|
23
|
+
ssh_options[:keys] = "<%= @app_server_user_key %>"
|
|
24
|
+
|
|
25
|
+
set :user, "<%= @app_deployer_user_name %>"
|
|
26
|
+
set :group, "<%= @app_deployer_user_group %>"
|
|
27
|
+
set :deploy_to, "#{File.expand_path('auto_deployment', '~')}"
|
|
28
|
+
set :use_sudo, false
|
|
29
|
+
|
|
30
|
+
namespace :deploy do
|
|
31
|
+
task :start do ; end
|
|
32
|
+
task :stop do ; end
|
|
33
|
+
|
|
34
|
+
desc "Restart the application"
|
|
35
|
+
task :restart, :roles => :app, :except => { :no_release => true } do
|
|
36
|
+
run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
desc "Copy the database.yml file into the latest release"
|
|
40
|
+
task :copy_in_database_yml do
|
|
41
|
+
run "cp #{shared_path}/config/database.yml #{latest_release}/config/"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
desc "Will create database if not exists"
|
|
45
|
+
task :prepare_database do
|
|
46
|
+
db_name = "<%= @db_name.empty? ? @app_name : @db_name %>"
|
|
47
|
+
username = "<%= @db_user_name.empty? ? @app_name : @db_user_name %>"
|
|
48
|
+
password = "<%= @db_user_password %>"
|
|
49
|
+
source_host = "<%= @db_source_host %>"
|
|
50
|
+
admin_user = "<%= @db_admin_user %>"
|
|
51
|
+
admin_password = "<%= @db_admin_password %>"
|
|
52
|
+
run %Q|mysql -u#{admin_user} -p#{admin_password} -e "CREATE DATABASE IF NOT EXISTS #{db_name}"|
|
|
53
|
+
run %Q|mysql -u#{admin_user} -p#{admin_password} -e "GRANT ALL PRIVILEGES ON #{db_name}.* TO '#{username}'@'#{source_host}' IDENTIFIED BY '#{password}'"|
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#currently we have database.yml in git repo, will move it out later
|
|
58
|
+
#before "deploy:assets:precompile", "deploy:copy_in_database_yml"
|
|
59
|
+
before 'deploy:setup', 'rvm:install_ruby'
|
|
60
|
+
before 'deploy:migrate', 'deploy:prepare_database'
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
|
|
3
|
+
def debug(message)
|
|
4
|
+
logger = Logger.new(STDOUT)
|
|
5
|
+
logger.debug ">>>>>>>>>>>>>>>DEBUG START<<<<<<<<<<<<<<<"
|
|
6
|
+
logger.debug message
|
|
7
|
+
logger.debug ">>>>>>>>>>>>>>>DEBUG ENG<<<<<<<<<<<<<<<"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def info_to_console(message)
|
|
11
|
+
puts message
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def error_to_console(message)
|
|
15
|
+
puts "Error: #{message}"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def log_to_file(message)
|
|
19
|
+
FileLog.new.info(message)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def error_to_file(message)
|
|
23
|
+
FileLog.new.error(message)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def info(message)
|
|
27
|
+
info_to_console message
|
|
28
|
+
log_to_file message
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def error(message)
|
|
32
|
+
error_to_console message
|
|
33
|
+
error_to_file message
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def run_command(cmd)
|
|
37
|
+
Process.abort "Failed to run command #{cmd}" unless system cmd
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def reset_dir(dir)
|
|
41
|
+
FileUtils.rm_rf dir if File.exist? dir
|
|
42
|
+
FileUtils.mkdir_p dir
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def require_dir(dir)
|
|
46
|
+
Dir.foreach(dir) do |entry|
|
|
47
|
+
absolute_path = File.join(dir, entry)
|
|
48
|
+
next if (entry == "." || entry == "..")
|
|
49
|
+
require absolute_path if (File.file?(absolute_path) && absolute_path.end_with?("rb"))
|
|
50
|
+
require_dir(absolute_path) if File.directory?(absolute_path)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def read_all file
|
|
55
|
+
IO.readlines(file).join
|
|
56
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module MoodeAutoDeployKit module Remote
|
|
2
|
+
|
|
3
|
+
def remote_server
|
|
4
|
+
$config.deployer_host
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def base_options
|
|
8
|
+
{
|
|
9
|
+
:body => {
|
|
10
|
+
:app_name => $config.app_name,
|
|
11
|
+
:app_server => $config.app_server,
|
|
12
|
+
:db_name => $config.db_name,
|
|
13
|
+
:db_user_name => $config.db_user_name,
|
|
14
|
+
:db_user_password => $config.db_user_password,
|
|
15
|
+
:repository_name => repository_name,
|
|
16
|
+
:repository_branch_remote => $config.repository_branch_remote
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def repository_name
|
|
22
|
+
$config.repository_url.match(/^.*\/(.*)\.git$/)[1]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'httparty'
|
|
2
|
+
|
|
3
|
+
module MoodeAutoDeployKit
|
|
4
|
+
module RemoteDomain
|
|
5
|
+
include Remote
|
|
6
|
+
|
|
7
|
+
def create_domain
|
|
8
|
+
response = HTTParty.post(create_domain_url, create_domain_options)
|
|
9
|
+
puts response.body, response.code, response.message
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def create_domain_url
|
|
15
|
+
"#{remote_server}/domain"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def create_domain_options
|
|
19
|
+
options = base_options
|
|
20
|
+
options[:body][:dns_name] = $config.dns_name
|
|
21
|
+
options
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'httparty'
|
|
2
|
+
|
|
3
|
+
module MoodeAutoDeployKit
|
|
4
|
+
module RemoteJob
|
|
5
|
+
include Remote
|
|
6
|
+
|
|
7
|
+
def create_job
|
|
8
|
+
response = HTTParty.post(create_job_url, create_job_options)
|
|
9
|
+
puts response.body, response.code, response.message
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def create_job_url
|
|
15
|
+
"#{remote_server}/job"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def create_job_options
|
|
19
|
+
options = base_options
|
|
20
|
+
options[:body][:job_name] = $config.job_name
|
|
21
|
+
options
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require "erb"
|
|
3
|
+
require "fileutils"
|
|
4
|
+
|
|
5
|
+
module MoodeAutoDeployKit
|
|
6
|
+
module ScriptProvider
|
|
7
|
+
def create_script root_dir
|
|
8
|
+
puts "Creating scripts to #{root_dir}"
|
|
9
|
+
app_root_dir = File.join(root_dir, 'app')
|
|
10
|
+
server_root_dir = File.join(root_dir, 'server')
|
|
11
|
+
|
|
12
|
+
copy_templates_to_working_dir
|
|
13
|
+
render_templates_according_to_config
|
|
14
|
+
copy_generated_scripts_to_target_dir root_dir
|
|
15
|
+
modify_server_gemfile server_root_dir
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def modify_server_gemfile server_root_dir
|
|
21
|
+
extra_server_gems = IO.readlines($fs.server_gemfile).join
|
|
22
|
+
target_server_gem_file = File.join(server_root_dir, 'Gemfile')
|
|
23
|
+
gemfile_content = IO.readlines(target_server_gem_file).join
|
|
24
|
+
unless gemfile_content.include? extra_server_gems
|
|
25
|
+
gemfile_content += extra_server_gems
|
|
26
|
+
end
|
|
27
|
+
File.open(target_server_gem_file, 'w') { |file| file.write(gemfile_content) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def copy_templates_to_working_dir
|
|
31
|
+
working_dir = $fs.deploy_script_working_dir
|
|
32
|
+
reset_dir working_dir
|
|
33
|
+
FileUtils.cp_r "#{$fs.deploy_script_template_dir}/.", working_dir
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def render_templates_according_to_config
|
|
37
|
+
templates = []
|
|
38
|
+
get_template_list($fs.deploy_script_working_dir, templates)
|
|
39
|
+
templates.each { |template| render_template(template, $config) }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def copy_generated_scripts_to_target_dir root_dir
|
|
43
|
+
FileUtils.cp_r "#{$fs.deploy_script_working_dir}/.", root_dir
|
|
44
|
+
FileUtils.rm_rf $fs.working
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def render_template(template_file, config)
|
|
48
|
+
puts "Rendering template #{template_file}"
|
|
49
|
+
template = ERB.new(IO.readlines(template_file).join)
|
|
50
|
+
script_content = template.result($config.get_binding)
|
|
51
|
+
File.open(template_file, 'w') { |file| file.write(script_content) }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def get_template_list(dir, templates)
|
|
55
|
+
Dir.foreach(dir) do |entry|
|
|
56
|
+
absolute_path = File.join(dir, entry)
|
|
57
|
+
next if (entry == "." || entry == "..")
|
|
58
|
+
templates << absolute_path if File.file?(absolute_path)
|
|
59
|
+
get_template_list(absolute_path, templates) if File.directory?(absolute_path)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
require "moode_auto_deploy_kit/version"
|
|
2
|
+
require "moode_auto_deploy_kit/script_provider"
|
|
3
|
+
require "moode_auto_deploy_kit/remote"
|
|
4
|
+
require "moode_auto_deploy_kit/remote_job"
|
|
5
|
+
require "moode_auto_deploy_kit/remote_domain"
|
|
6
|
+
infra_dir = File.expand_path('../moode_auto_deploy_kit/infra', __FILE__)
|
|
7
|
+
require File.join(infra_dir, "utils")
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'moode_auto_deploy_kit/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "moode_auto_deploy_kit"
|
|
8
|
+
spec.version = MoodeAutoDeployKit::VERSION
|
|
9
|
+
spec.authors = ["lishoubo"]
|
|
10
|
+
spec.email = ["litttlan@gmail.com"]
|
|
11
|
+
spec.description = %q{apply auto deploy scripts to project}
|
|
12
|
+
spec.summary = %q{apply auto deploy scripts to project}
|
|
13
|
+
spec.homepage = ""
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files`.split($/)
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
spec.add_dependency "thor", '~> 0.17.0'
|
|
22
|
+
spec.add_dependency 'httparty', '~> 0.10.2'
|
|
23
|
+
|
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
|
25
|
+
spec.add_development_dependency "rake"
|
|
26
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: moode_auto_deploy_kit
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- lishoubo
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2013-03-12 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: thor
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ~>
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: 0.17.0
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ~>
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: 0.17.0
|
|
30
|
+
- !ruby/object:Gem::Dependency
|
|
31
|
+
name: httparty
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
33
|
+
none: false
|
|
34
|
+
requirements:
|
|
35
|
+
- - ~>
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: 0.10.2
|
|
38
|
+
type: :runtime
|
|
39
|
+
prerelease: false
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ~>
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: 0.10.2
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: bundler
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
none: false
|
|
50
|
+
requirements:
|
|
51
|
+
- - ~>
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.3'
|
|
54
|
+
type: :development
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - ~>
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '1.3'
|
|
62
|
+
- !ruby/object:Gem::Dependency
|
|
63
|
+
name: rake
|
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
|
65
|
+
none: false
|
|
66
|
+
requirements:
|
|
67
|
+
- - ! '>='
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '0'
|
|
70
|
+
type: :development
|
|
71
|
+
prerelease: false
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ! '>='
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '0'
|
|
78
|
+
description: apply auto deploy scripts to project
|
|
79
|
+
email:
|
|
80
|
+
- litttlan@gmail.com
|
|
81
|
+
executables:
|
|
82
|
+
- deploy_kit
|
|
83
|
+
extensions: []
|
|
84
|
+
extra_rdoc_files: []
|
|
85
|
+
files:
|
|
86
|
+
- .gitignore
|
|
87
|
+
- Gemfile
|
|
88
|
+
- LICENSE.txt
|
|
89
|
+
- README.md
|
|
90
|
+
- Rakefile
|
|
91
|
+
- bin/deploy_kit
|
|
92
|
+
- deploy_config.rb
|
|
93
|
+
- deploy_scripts/configs/deploy_config.json
|
|
94
|
+
- deploy_scripts/gemfiles/server_gemfile
|
|
95
|
+
- deploy_scripts/templates/app/assets/www/.rvmrc
|
|
96
|
+
- deploy_scripts/templates/app/deploy.sh
|
|
97
|
+
- deploy_scripts/templates/deploy.sh
|
|
98
|
+
- deploy_scripts/templates/scripts/common/common.sh
|
|
99
|
+
- deploy_scripts/templates/scripts/common/dir_structure.sh
|
|
100
|
+
- deploy_scripts/templates/scripts/common/infra.sh
|
|
101
|
+
- deploy_scripts/templates/scripts/config.sh
|
|
102
|
+
- deploy_scripts/templates/scripts/deploy/deploy.sh
|
|
103
|
+
- deploy_scripts/templates/scripts/deploy/post_deployment.sh
|
|
104
|
+
- deploy_scripts/templates/scripts/deploy/pre_deployment.sh
|
|
105
|
+
- deploy_scripts/templates/server/.rvmrc
|
|
106
|
+
- deploy_scripts/templates/server/Capfile
|
|
107
|
+
- deploy_scripts/templates/server/config/database.yml
|
|
108
|
+
- deploy_scripts/templates/server/config/deploy.rb
|
|
109
|
+
- deploy_scripts/templates/server/deploy.sh
|
|
110
|
+
- lib/moode_auto_deploy_kit.rb
|
|
111
|
+
- lib/moode_auto_deploy_kit/infra/utils.rb
|
|
112
|
+
- lib/moode_auto_deploy_kit/remote.rb
|
|
113
|
+
- lib/moode_auto_deploy_kit/remote_domain.rb
|
|
114
|
+
- lib/moode_auto_deploy_kit/remote_job.rb
|
|
115
|
+
- lib/moode_auto_deploy_kit/script_provider.rb
|
|
116
|
+
- lib/moode_auto_deploy_kit/version.rb
|
|
117
|
+
- moode_auto_deploy_kit.gemspec
|
|
118
|
+
homepage: ''
|
|
119
|
+
licenses:
|
|
120
|
+
- MIT
|
|
121
|
+
post_install_message:
|
|
122
|
+
rdoc_options: []
|
|
123
|
+
require_paths:
|
|
124
|
+
- lib
|
|
125
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
126
|
+
none: false
|
|
127
|
+
requirements:
|
|
128
|
+
- - ! '>='
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: '0'
|
|
131
|
+
segments:
|
|
132
|
+
- 0
|
|
133
|
+
hash: -3634374342245414110
|
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
|
+
none: false
|
|
136
|
+
requirements:
|
|
137
|
+
- - ! '>='
|
|
138
|
+
- !ruby/object:Gem::Version
|
|
139
|
+
version: '0'
|
|
140
|
+
segments:
|
|
141
|
+
- 0
|
|
142
|
+
hash: -3634374342245414110
|
|
143
|
+
requirements: []
|
|
144
|
+
rubyforge_project:
|
|
145
|
+
rubygems_version: 1.8.25
|
|
146
|
+
signing_key:
|
|
147
|
+
specification_version: 3
|
|
148
|
+
summary: apply auto deploy scripts to project
|
|
149
|
+
test_files: []
|