gta 0.1.2 → 0.2.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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/gta.gemspec +1 -1
- data/lib/gta.rb +5 -0
- data/lib/gta/db.rb +57 -0
- data/lib/gta/heroku_db.rb +38 -0
- data/lib/gta/hotfix.rb +41 -0
- data/lib/gta/local_db.rb +40 -0
- data/lib/gta/manager.rb +18 -1
- data/lib/gta/railtie.rb +7 -0
- data/lib/gta/stage.rb +20 -3
- data/lib/gta/tag_finder.rb +22 -0
- data/lib/gta/tasks.rb +4 -0
- data/lib/gta/tasks/deploy.rake +43 -40
- data/lib/gta/tasks/gta.rake +0 -2
- data/lib/gta/tasks/heroku_db.rake +24 -0
- data/lib/gta/tasks/hotfix.rake +15 -0
- data/lib/gta/version.rb +1 -1
- data/spec/db_spec.rb +154 -0
- data/spec/fixtures/config/database.yml +3 -0
- data/spec/fixtures/config/gta.yml +21 -15
- data/spec/heroku_db_spec.rb +40 -0
- data/spec/hotfix_spec.rb +76 -0
- data/spec/local_db_spec.rb +16 -0
- data/spec/manager_spec.rb +54 -0
- data/spec/stage_spec.rb +5 -3
- data/spec/tag_finder_spec.rb +50 -0
- metadata +23 -3
- data/lib/gta/remote_db.rb +0 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6282ea52c54d66479c7bb48a0429f8e4e4113ef7
|
|
4
|
+
data.tar.gz: c1e27e7e8a29454847b5081109aeb2a6ae4444e0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 817bcf144b42c8e96c56f0ec3709d1fcc8c1f217a1bbb15c3f7bce9428645569fe4817fa2279c0f179b75ac65f6a21619769694c82b3a77c62f817fc788e4765
|
|
7
|
+
data.tar.gz: 16cfc6bc1416af0080822bf1fef98a585421e59fc58c9684789080dc6e47a4567f19c456a18287f685f8e524e85ddee58b975f61d04f83d6b5f937a6f2ca62c1
|
data/.gitignore
CHANGED
data/gta.gemspec
CHANGED
|
@@ -6,7 +6,7 @@ require 'gta/version'
|
|
|
6
6
|
Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "gta"
|
|
8
8
|
spec.version = GTA::VERSION
|
|
9
|
-
spec.authors = ["socialchorus", "Kane Baccigalupi"]
|
|
9
|
+
spec.authors = ["socialchorus", "Kane Baccigalupi", "Ian Cooper"]
|
|
10
10
|
spec.email = ["developers@socialchorus.com"]
|
|
11
11
|
spec.description = %q{GTA: the Git Transit Authority - A git based deploy tool for moving code from stage to stage.}
|
|
12
12
|
spec.summary = %q{GTA: the Git Transit Authority - A git based deploy tool for moving code from stage to stage.}
|
data/lib/gta.rb
CHANGED
data/lib/gta/db.rb
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module GTA
|
|
2
|
+
class DB
|
|
3
|
+
attr_reader :gta_config_path, :database_config_path, :local_env
|
|
4
|
+
|
|
5
|
+
def initialize(gta_config_path=nil, database_config_path=nil, local_env=nil)
|
|
6
|
+
@gta_config_path = gta_config_path
|
|
7
|
+
@database_config_path = database_config_path
|
|
8
|
+
@local_env = local_env || 'development'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def manager
|
|
12
|
+
@manager ||= Manager.new(gta_config_path)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def local_db
|
|
16
|
+
@local_db ||= LocalDB.new(local_env, database_config_path)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def fetch(stage_name=nil)
|
|
20
|
+
stage = stage_or_final(stage_name)
|
|
21
|
+
db(stage.name).fetch
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def load(stage_name=nil)
|
|
25
|
+
stage = stage_or_final(stage_name)
|
|
26
|
+
heroku_db = db(stage.name)
|
|
27
|
+
local_db.load(heroku_db.file_name)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def pull(stage_name=nil)
|
|
31
|
+
stage = stage_or_final(stage_name)
|
|
32
|
+
fetch(stage.name)
|
|
33
|
+
self.load(stage.name)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def restore(destination_name, source_name=nil)
|
|
37
|
+
source = stage_or_final(source_name)
|
|
38
|
+
destination = manager.stage!(destination_name)
|
|
39
|
+
|
|
40
|
+
raise "cannot restore #{destination.name}" unless destination.restorable?
|
|
41
|
+
|
|
42
|
+
source_db = db(source.name)
|
|
43
|
+
source_db.backup
|
|
44
|
+
|
|
45
|
+
destination_db = db(destination.name)
|
|
46
|
+
destination_db.restore_from(source_db.url)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def stage_or_final(stage_name)
|
|
50
|
+
manager.stage(stage_name) || manager.final_stage
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def db(stage_name)
|
|
54
|
+
HerokuDB.new(manager.app_name, stage_name)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module GTA
|
|
2
|
+
class HerokuDB
|
|
3
|
+
include GTA::Sh
|
|
4
|
+
|
|
5
|
+
attr_reader :env, :app, :database_yml_path
|
|
6
|
+
|
|
7
|
+
def initialize(app, env)
|
|
8
|
+
@env = env
|
|
9
|
+
@app = app
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def url
|
|
13
|
+
# using backticks in order to get the bash response
|
|
14
|
+
`heroku pgbackups:url --app #{app_signature}`
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def backup
|
|
18
|
+
sh("heroku pgbackups:capture --expire --app #{app_signature}")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def restore_from(url)
|
|
22
|
+
sh("heroku pgbackups:restore DATABASE_URL \"#{url}\" --app #{app_signature} --confirm #{app_signature}")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def fetch
|
|
26
|
+
sh("curl -o #{file_name} \"#{url}\"")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def file_name
|
|
30
|
+
"~/Downloads/#{app_signature}.sql"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def app_signature
|
|
34
|
+
"#{app}-#{env}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
data/lib/gta/hotfix.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module GTA
|
|
2
|
+
class Hotfix
|
|
3
|
+
attr_reader :gta_config_path
|
|
4
|
+
|
|
5
|
+
def initialize(gta_config_path = nil)
|
|
6
|
+
@gta_config_path = gta_config_path
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def checkout(stage_name=nil)
|
|
10
|
+
stage = stage_for(stage_name)
|
|
11
|
+
not_hotfixable!(stage_name) unless stage
|
|
12
|
+
stage.checkout
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def manager
|
|
16
|
+
@manager ||= Manager.new(gta_config_path)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def deploy
|
|
20
|
+
stage_name = branch_name
|
|
21
|
+
stage = stage_for(stage_name)
|
|
22
|
+
not_hotfixable!(stage_name) if !stage || !stage_name
|
|
23
|
+
sh "git push #{stage_name} #{stage_name}:master"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def not_hotfixable!(stage_name)
|
|
27
|
+
raise "stage #{stage_name} not hotfixable"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def stage_for(stage_name)
|
|
31
|
+
manager.hotfixer(stage_name)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def branch_name
|
|
35
|
+
# using `` because we need the bash output
|
|
36
|
+
branches = `git branch`
|
|
37
|
+
matches = branches.match(/\*\s+(.*)/)
|
|
38
|
+
matches[1].strip if matches
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
data/lib/gta/local_db.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module GTA
|
|
2
|
+
class LocalDB
|
|
3
|
+
include Sh
|
|
4
|
+
|
|
5
|
+
attr_reader :database_config_path, :env
|
|
6
|
+
|
|
7
|
+
def initialize(env, database_config_path=nil)
|
|
8
|
+
@env = env
|
|
9
|
+
@database_config_path = database_config_path || self.class.default_database_config_path
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def load(backup_path)
|
|
13
|
+
sh "pg_restore --verbose --clean --no-acl --no-owner -h localhost#{username}#{database} #{backup_path}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def config
|
|
17
|
+
@config ||= YAML.load(File.read(database_config_path))[env]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def username
|
|
21
|
+
config['username'] ? " -U #{config['username']}" : ''
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def database
|
|
25
|
+
config['database'] ? " -d #{config['database']}" : ''
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.default_database_config_path
|
|
29
|
+
"#{Dir.pwd}/config/database.yml"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.env_config
|
|
33
|
+
ENV['GTA_DATABASE_CONFIG_PATH']
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.local_database_env
|
|
37
|
+
ENV['RAILS_ENV'] || ENV['GTA_LOCAL_ENV']
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/lib/gta/manager.rb
CHANGED
|
@@ -16,6 +16,10 @@ module GTA
|
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
+
def app_name
|
|
20
|
+
@app_name || config && @app_name
|
|
21
|
+
end
|
|
22
|
+
|
|
19
23
|
def checkout(name)
|
|
20
24
|
stage!(name).checkout
|
|
21
25
|
end
|
|
@@ -31,7 +35,10 @@ module GTA
|
|
|
31
35
|
end
|
|
32
36
|
|
|
33
37
|
def config
|
|
34
|
-
@config
|
|
38
|
+
return @config if @config
|
|
39
|
+
parsed = YAML.load(File.read(config_path))
|
|
40
|
+
@app_name = parsed.keys.first
|
|
41
|
+
@config = parsed.values.first
|
|
35
42
|
end
|
|
36
43
|
|
|
37
44
|
def stages
|
|
@@ -42,6 +49,16 @@ module GTA
|
|
|
42
49
|
stages.detect{|s| s.name == name.to_s}
|
|
43
50
|
end
|
|
44
51
|
|
|
52
|
+
def final_stage
|
|
53
|
+
stages.detect{|s| s.final? } || stages.last
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def hotfixer(stage_name=nil)
|
|
57
|
+
hotfixers = stages.select{|s| s.hotfixable?}
|
|
58
|
+
default = stage_name == nil ? hotfixers.first : nil
|
|
59
|
+
hotfixers.detect{|s| s.name == stage_name} || default
|
|
60
|
+
end
|
|
61
|
+
|
|
45
62
|
def stage!(name)
|
|
46
63
|
stage(name) || (raise ArgumentError.new("Stage #{name} not found"))
|
|
47
64
|
end
|
data/lib/gta/railtie.rb
ADDED
data/lib/gta/stage.rb
CHANGED
|
@@ -2,7 +2,8 @@ module GTA
|
|
|
2
2
|
class Stage
|
|
3
3
|
include Sh
|
|
4
4
|
|
|
5
|
-
attr_reader :name, :repository, :source_name, :branch, :tag, :manager
|
|
5
|
+
attr_reader :name, :repository, :source_name, :branch, :tag, :manager,
|
|
6
|
+
:final, :hotfixable, :restorable
|
|
6
7
|
|
|
7
8
|
def initialize(name, manager, opts)
|
|
8
9
|
@name = name
|
|
@@ -11,6 +12,9 @@ module GTA
|
|
|
11
12
|
@source_name = opts['source']
|
|
12
13
|
@branch = opts['branch'] || 'master'
|
|
13
14
|
@tag = opts['tag']
|
|
15
|
+
@final = opts['final']
|
|
16
|
+
@hotfixable = opts['hotfixable']
|
|
17
|
+
@restorable = opts['restorable']
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
def stages
|
|
@@ -45,11 +49,24 @@ module GTA
|
|
|
45
49
|
end
|
|
46
50
|
|
|
47
51
|
def ==(other)
|
|
48
|
-
|
|
52
|
+
other.is_a?(self.class) &&
|
|
53
|
+
name == other.name &&
|
|
49
54
|
branch == other.branch &&
|
|
50
55
|
tag == other.tag
|
|
51
56
|
end
|
|
52
57
|
|
|
58
|
+
def final?
|
|
59
|
+
!!final
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def restorable?
|
|
63
|
+
!!restorable
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def hotfixable?
|
|
67
|
+
!!hotfixable
|
|
68
|
+
end
|
|
69
|
+
|
|
53
70
|
# -----------
|
|
54
71
|
|
|
55
72
|
def source_from(s)
|
|
@@ -57,7 +74,7 @@ module GTA
|
|
|
57
74
|
end
|
|
58
75
|
|
|
59
76
|
def source_ref
|
|
60
|
-
tag || "#{name}
|
|
77
|
+
TagFinder.new(tag).newest || "#{name}"
|
|
61
78
|
end
|
|
62
79
|
|
|
63
80
|
def push_command(source_ref, forced=nil)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module GTA
|
|
2
|
+
class TagFinder
|
|
3
|
+
attr_reader :tag
|
|
4
|
+
|
|
5
|
+
def initialize(tag)
|
|
6
|
+
@tag = tag
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def newest
|
|
10
|
+
return unless tag
|
|
11
|
+
tags.last
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def tag_list
|
|
15
|
+
`git tag -l #{tag}`
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def tags
|
|
19
|
+
tag_list.split(/\s/)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/gta/tasks.rb
CHANGED
data/lib/gta/tasks/deploy.rake
CHANGED
|
@@ -1,44 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
namespace :gta do
|
|
2
|
+
namespace :deploy do
|
|
3
|
+
desc 'task that will be run before a deploy'
|
|
4
|
+
task :before, :stage_name
|
|
5
|
+
|
|
6
|
+
desc 'task that will be run after a deploy'
|
|
7
|
+
task :after, :stage_name
|
|
8
|
+
|
|
9
|
+
def gta_manager(args={})
|
|
10
|
+
return @manager if @manager
|
|
11
|
+
raise GTA::Manager.stage_name_error unless stage_name = args[:stage_name]
|
|
12
|
+
@manager = GTA::Manager.new(GTA::Manager.env_config)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# the meat of a deploy, a git push from source to destination
|
|
16
|
+
task :gta_push, :stage_name do |t, args|
|
|
17
|
+
stage_name = args[:stage_name]
|
|
18
|
+
gta_manager(args).push_to(stage_name)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# a forced version of the meat of the matter
|
|
22
|
+
task :gta_force_push, :stage_name do |t, args|
|
|
23
|
+
stage_name = args[:stage_name]
|
|
24
|
+
gta_manager(args).push_to(stage_name, :force)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
task :deploy, :stage_name do |t, args|
|
|
28
|
+
stage_name = args[:stage_name]
|
|
29
|
+
Rake::Task["gta:deploy:before"].invoke(stage_name)
|
|
30
|
+
Rake::Task["gta:deploy:gta_push"].invoke(stage_name)
|
|
31
|
+
Rake::Task["gta:deploy:after"].invoke(stage_name)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
desc 'force push deploy, running before and after tasks'
|
|
35
|
+
task :force, :stage_name do |t, args|
|
|
36
|
+
stage_name = args[:stage_name]
|
|
37
|
+
Rake::Task["gta:deploy:before"].invoke(stage_name)
|
|
38
|
+
Rake::Task["gta:deploy:gta_force_push"].invoke(stage_name)
|
|
39
|
+
Rake::Task["gta:deploy:after"].invoke(stage_name)
|
|
40
|
+
end
|
|
22
41
|
end
|
|
23
42
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Rake::Task["deploy:
|
|
27
|
-
Rake::Task["deploy:gta_push"].invoke(stage_name)
|
|
28
|
-
Rake::Task["deploy:before"].invoke(stage_name)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
desc 'force push deploy, running before and after tasks'
|
|
32
|
-
task :force, :stage_name do |t, args|
|
|
33
|
-
stage_name = args[:stage_name]
|
|
34
|
-
Rake::Task["deploy:before"].invoke(stage_name)
|
|
35
|
-
Rake::Task["deploy:gta_force_push"].invoke(stage_name)
|
|
36
|
-
Rake::Task["deploy:before"].invoke(stage_name)
|
|
43
|
+
desc "push deploy, running before and after tasks"
|
|
44
|
+
task :deploy, :stage_name do |t, args|
|
|
45
|
+
Rake::Task["gta:deploy:deploy"].invoke(args[:stage_name])
|
|
37
46
|
end
|
|
38
47
|
end
|
|
39
|
-
|
|
40
|
-
desc "push deploy, running before and after tasks"
|
|
41
|
-
task :deploy, :stage_name do |t, args|
|
|
42
|
-
Rake::Task["deploy:wrap"].invoke(args[:stage_name])
|
|
43
|
-
end
|
|
44
|
-
|
data/lib/gta/tasks/gta.rake
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
namespace :gta do
|
|
2
|
+
namespace :heroku do
|
|
3
|
+
namespace :db do
|
|
4
|
+
def gta_db
|
|
5
|
+
@gta_db ||= GTA::DB.new(GTA::Manager.env_config, GTA::LocalDB.env_config, GTA::LocalDB.local_database_env)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
desc 'download the database from the specified stage or from the last stage'
|
|
9
|
+
task :fetch, :stage_name do |t, args|
|
|
10
|
+
gta_db.fetch(args[:stage_name])
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
desc 'load local database with downloaded backup from stage'
|
|
14
|
+
task :load, :stage_name do |t, args|
|
|
15
|
+
gta_db.load(args[:stage_name])
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
desc 'restore remote database from another stage'
|
|
19
|
+
task :restore, :stage_name do |t, args|
|
|
20
|
+
gta_db.restore(args[:stage_name], ENV['source'])
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
namespace :gta do
|
|
2
|
+
namespace :hotfix do
|
|
3
|
+
desc "Checkout a stage for hotfix change and future deploy"
|
|
4
|
+
task :checkout, :stage_name do |t, args|
|
|
5
|
+
hotfix = GTA::Hotfix.new(GTA::Manager.env_config)
|
|
6
|
+
hotfix.checkout(args[:stage_name])
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
desc "deploy checked out branch to that remote"
|
|
10
|
+
task :deploy do
|
|
11
|
+
hotfix = GTA::Hotfix.new(GTA::Manager.env_config)
|
|
12
|
+
hotfix.deploy
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/gta/version.rb
CHANGED
data/spec/db_spec.rb
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe GTA::DB do
|
|
4
|
+
let(:config_path) { File.dirname(__FILE__) + "/fixtures/config" }
|
|
5
|
+
let(:gta_config_path) { "#{config_path}/gta.yml" }
|
|
6
|
+
let(:database_config_path) { "#{config_path}/database.yml" }
|
|
7
|
+
let(:db) { GTA::DB.new(gta_config_path, database_config_path) }
|
|
8
|
+
let(:heroku_db) { double(fetch: true) }
|
|
9
|
+
|
|
10
|
+
before do
|
|
11
|
+
GTA::HerokuDB.stub(:new).and_return(heroku_db)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "has a manager" do
|
|
15
|
+
db.manager.should be_a(GTA::Manager)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "#fetch" do
|
|
19
|
+
context "when a stage is provided" do
|
|
20
|
+
it "will construct a heroku db object with the right stage information" do
|
|
21
|
+
GTA::HerokuDB.should_receive(:new)
|
|
22
|
+
.with('activator', 'staging')
|
|
23
|
+
.and_return(heroku_db)
|
|
24
|
+
db.fetch('staging')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "will call #fetch on the heroku db object" do
|
|
28
|
+
heroku_db.should_receive(:fetch)
|
|
29
|
+
db.fetch('staging')
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context "when a stage is not provided" do
|
|
34
|
+
it "will use the default stage" do
|
|
35
|
+
GTA::HerokuDB.should_receive(:new)
|
|
36
|
+
.with('activator', 'qa')
|
|
37
|
+
.and_return(heroku_db)
|
|
38
|
+
db.fetch
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe '#load' do
|
|
44
|
+
let(:local_db) { double('local_db') }
|
|
45
|
+
|
|
46
|
+
before do
|
|
47
|
+
db.stub(:local_db).and_return(local_db)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context "when no source is given" do
|
|
51
|
+
it "loads the last stage's download into the local database" do
|
|
52
|
+
GTA::HerokuDB.should_receive(:new)
|
|
53
|
+
.with('activator', 'qa')
|
|
54
|
+
.and_return(heroku_db)
|
|
55
|
+
heroku_db.stub(:file_name).and_return("~/Downloads/activator-qa.sql")
|
|
56
|
+
local_db.should_receive(:load).with("~/Downloads/activator-qa.sql")
|
|
57
|
+
db.load
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
context "when a source is passed" do
|
|
62
|
+
it "loads the source download into the local database" do
|
|
63
|
+
GTA::HerokuDB.should_receive(:new)
|
|
64
|
+
.with('activator', 'production')
|
|
65
|
+
.and_return(heroku_db)
|
|
66
|
+
heroku_db.stub(:file_name).and_return("~/Downloads/activator-production.sql")
|
|
67
|
+
local_db.should_receive(:load).with("~/Downloads/activator-production.sql")
|
|
68
|
+
db.load('production')
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
describe '#pull' do
|
|
74
|
+
it "calls #fetch with the source (default or other)" do
|
|
75
|
+
db.should_receive(:fetch).with('qa')
|
|
76
|
+
db.should_receive(:load).with('qa')
|
|
77
|
+
db.pull
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "calls #load with the source (default or other)" do
|
|
81
|
+
db.should_receive(:fetch).with('production')
|
|
82
|
+
db.should_receive(:load).with('production')
|
|
83
|
+
db.pull('production')
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
describe '#restore' do
|
|
88
|
+
let(:manager) { db.manager }
|
|
89
|
+
let(:source_heroku_db) { double('source db', backup: true, url: 'source-url') }
|
|
90
|
+
let(:destination_heroku_db) { double('distination db', restore_from: true) }
|
|
91
|
+
|
|
92
|
+
context 'when the destination stage is not restorable' do
|
|
93
|
+
it "raises an error" do
|
|
94
|
+
expect {
|
|
95
|
+
db.restore('production')
|
|
96
|
+
}.to raise_error
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
context "when the stage is restorable, and no source stage information is given" do
|
|
101
|
+
before do
|
|
102
|
+
GTA::HerokuDB.stub(:new) do |app_name, stage_name|
|
|
103
|
+
if stage_name == 'qa'
|
|
104
|
+
source_heroku_db
|
|
105
|
+
elsif stage_name == 'staging'
|
|
106
|
+
destination_heroku_db
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "makes a backup of the final stage" do
|
|
112
|
+
source_heroku_db.should_receive(:backup)
|
|
113
|
+
db.restore('staging')
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "gets the url for the final stage's database" do
|
|
117
|
+
source_heroku_db.should_receive(:url).and_return('source-url')
|
|
118
|
+
db.restore('staging')
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "calls restore on the destination stage with the database url" do
|
|
122
|
+
destination_heroku_db.should_receive(:restore_from).with('source-url')
|
|
123
|
+
db.restore('staging')
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
context "when a second 'source' stage is specified" do
|
|
128
|
+
before do
|
|
129
|
+
GTA::HerokuDB.stub(:new) do |app_name, stage_name|
|
|
130
|
+
if stage_name == 'production'
|
|
131
|
+
source_heroku_db
|
|
132
|
+
elsif stage_name == 'qa'
|
|
133
|
+
destination_heroku_db
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "makes a backup of the source stage" do
|
|
139
|
+
source_heroku_db.should_receive(:backup)
|
|
140
|
+
db.restore('qa', 'production')
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it "gets the url for the source's database" do
|
|
144
|
+
source_heroku_db.should_receive(:url).and_return('source-url')
|
|
145
|
+
db.restore('qa', 'production')
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it "calls restore on the destination stage with the database url" do
|
|
149
|
+
destination_heroku_db.should_receive(:restore_from).with('source-url')
|
|
150
|
+
db.restore('qa', 'production')
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
@@ -1,19 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
activator:
|
|
2
|
+
origin:
|
|
3
|
+
repository: git@github.com:socialchorus/activator.git
|
|
3
4
|
|
|
4
|
-
ci:
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
ci:
|
|
6
|
+
source: origin
|
|
7
|
+
tag: ci/*
|
|
8
|
+
repository: git@github.com:socialchorus/activator.git
|
|
7
9
|
|
|
8
|
-
staging:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
staging:
|
|
11
|
+
source: ci
|
|
12
|
+
repository: git@heroku.com:activator-staging.git
|
|
13
|
+
restorable: true
|
|
14
|
+
hotfixable: true
|
|
12
15
|
|
|
13
|
-
qa:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
qa:
|
|
17
|
+
source: staging
|
|
18
|
+
repository: git@heroku.com:activator-qa.git
|
|
19
|
+
restorable: true
|
|
20
|
+
final: true
|
|
21
|
+
hotfixable: true
|
|
16
22
|
|
|
17
|
-
production:
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
production:
|
|
24
|
+
source: qa
|
|
25
|
+
repository: git@heroku.com:activator-production.git
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe GTA::HerokuDB do
|
|
4
|
+
let(:database_yml_path) { File.dirname(__FILE__) + "/fixtures/config/database.yml" }
|
|
5
|
+
let(:heroku_db) { GTA::HerokuDB.new('activator', 'staging') }
|
|
6
|
+
|
|
7
|
+
describe '#url' do
|
|
8
|
+
it "gets the temporary database url from heroku" do
|
|
9
|
+
heroku_db.should_receive(:`)
|
|
10
|
+
.with("heroku pgbackups:url --app activator-staging")
|
|
11
|
+
.and_return('backup url')
|
|
12
|
+
heroku_db.url.should == 'backup url'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe '#backup' do
|
|
17
|
+
it "sends a heroku command to backup the databse, with the expire flag" do
|
|
18
|
+
heroku_db.should_receive(:sh)
|
|
19
|
+
.with("heroku pgbackups:capture --expire --app activator-staging")
|
|
20
|
+
heroku_db.backup
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe '#restore_from(url)' do
|
|
25
|
+
it "sends a heroku command to restore the database from the given url" do
|
|
26
|
+
heroku_db.should_receive(:sh)
|
|
27
|
+
.with('heroku pgbackups:restore DATABASE_URL "http://my-database-url.com" --app activator-staging --confirm activator-staging')
|
|
28
|
+
heroku_db.restore_from("http://my-database-url.com")
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe '#fetch' do
|
|
33
|
+
it "downloads the latest database backup to an appropriately named file in downloads" do
|
|
34
|
+
heroku_db.should_receive(:url).and_return('http://heroku-backup-url.com')
|
|
35
|
+
heroku_db.should_receive(:sh)
|
|
36
|
+
.with('curl -o ~/Downloads/activator-staging.sql "http://heroku-backup-url.com"')
|
|
37
|
+
heroku_db.fetch
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/spec/hotfix_spec.rb
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe GTA::Hotfix do
|
|
4
|
+
let(:gta_config_path) { File.dirname(__FILE__) + "/fixtures/config/gta.yml" }
|
|
5
|
+
let(:hotfix) { GTA::Hotfix.new(gta_config_path) }
|
|
6
|
+
let(:manager) { hotfix.manager }
|
|
7
|
+
let(:stage) { double(checkout: true) }
|
|
8
|
+
|
|
9
|
+
describe '#checkout' do
|
|
10
|
+
context "no stage provided" do
|
|
11
|
+
it "gets the first hotfixable stage" do
|
|
12
|
+
manager.should_receive(:hotfixer)
|
|
13
|
+
.and_return(stage)
|
|
14
|
+
hotfix.checkout
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "finds and checks out the first hotfixable stage" do
|
|
18
|
+
manager.should_receive(:hotfixer).with(nil).and_return(stage)
|
|
19
|
+
stage.should_receive(:checkout)
|
|
20
|
+
hotfix.checkout
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context "stage is not hotfixable" do
|
|
25
|
+
it "raises an error" do
|
|
26
|
+
expect {
|
|
27
|
+
hotfix.checkout('production')
|
|
28
|
+
}.to raise_error
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context "stage is hotfixable" do
|
|
33
|
+
it "checks out that stage" do
|
|
34
|
+
manager.should_receive(:hotfixer)
|
|
35
|
+
.with('staging')
|
|
36
|
+
.and_return(stage)
|
|
37
|
+
stage.should_receive(:checkout)
|
|
38
|
+
hotfix.checkout('staging')
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe '#deploy' do
|
|
44
|
+
context "when on a branch that maps to a stage" do
|
|
45
|
+
before do
|
|
46
|
+
hotfix.stub(:`).and_return(branch_output)
|
|
47
|
+
hotfix.stub(:sh)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context "if it is hotfixable" do
|
|
51
|
+
let(:branch_output) {
|
|
52
|
+
" bunny\n ftc_language\n* qa\n production"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
it "should call #sh with the right deploy command" do
|
|
56
|
+
hotfix.should_receive(:sh)
|
|
57
|
+
.with("git push qa qa:master")
|
|
58
|
+
.and_return("deploying")
|
|
59
|
+
hotfix.deploy.should == "deploying"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "if it is not hotfixable" do
|
|
64
|
+
let(:branch_output) {
|
|
65
|
+
" bunny\n ftc_language\n* master\n production"
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
it "raises an error" do
|
|
69
|
+
expect {
|
|
70
|
+
hotfix.deploy
|
|
71
|
+
}.to raise_error
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe GTA::LocalDB do
|
|
4
|
+
let(:env) { 'development' }
|
|
5
|
+
let(:database_config_path) { File.dirname(__FILE__) + "/fixtures/config/database.yml" }
|
|
6
|
+
let(:local_db) { GTA::LocalDB.new(env, database_config_path) }
|
|
7
|
+
|
|
8
|
+
describe '#load' do
|
|
9
|
+
it "does a postgres load of the right database based on the config" do
|
|
10
|
+
local_db.should_receive(:sh).with(
|
|
11
|
+
"pg_restore --verbose --clean --no-acl --no-owner -h localhost -U socialchorus -d activator_dev ~/Downloads/activator-staging.sql"
|
|
12
|
+
)
|
|
13
|
+
local_db.load("~/Downloads/activator-staging.sql")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/spec/manager_spec.rb
CHANGED
|
@@ -9,6 +9,10 @@ describe GTA::Manager do
|
|
|
9
9
|
manager.stages.map(&:class).uniq.should == [GTA::Stage]
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
it "has an app name" do
|
|
13
|
+
manager.app_name.should == 'activator'
|
|
14
|
+
end
|
|
15
|
+
|
|
12
16
|
describe '#fetch' do
|
|
13
17
|
it "loops through each stage and calls fetch" do
|
|
14
18
|
manager.stages.each do |stage|
|
|
@@ -37,6 +41,56 @@ describe GTA::Manager do
|
|
|
37
41
|
end
|
|
38
42
|
end
|
|
39
43
|
|
|
44
|
+
describe '#final_stage' do
|
|
45
|
+
context "when there are more than one final stages" do
|
|
46
|
+
before do
|
|
47
|
+
manager.stages.first.stub(:final?).and_return(true)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "returns the first stage that responds to #final? with true" do
|
|
51
|
+
manager.final_stage.should == manager.stages.first
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
context "when there is only one final stage" do
|
|
56
|
+
it "returns the only one defined" do
|
|
57
|
+
manager.final_stage.name.should == 'qa'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
context "when there are no final stages" do
|
|
62
|
+
before do
|
|
63
|
+
manager.stages.each{|s| s.stub(:final?).and_return(false) }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "chooses the last stage in the configuration" do
|
|
67
|
+
manager.final_stage.name.should == 'production'
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
describe '#hotfixer' do
|
|
73
|
+
context 'when not passed a stage name' do
|
|
74
|
+
it "returns the first stage that is hotfixable" do
|
|
75
|
+
manager.hotfixer.name.should == 'staging'
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context "when passed a stage name" do
|
|
80
|
+
context "when the stage name matches a hotfixable stage" do
|
|
81
|
+
it "returns the stage" do
|
|
82
|
+
manager.hotfixer('qa').name.should == 'qa'
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
context "when the stage name matches as non hotfixbale stage" do
|
|
87
|
+
it "returns nil" do
|
|
88
|
+
manager.hotfixer('production').should == nil
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
40
94
|
describe '#push_to' do
|
|
41
95
|
before do
|
|
42
96
|
manager.stub(:fetch)
|
data/spec/stage_spec.rb
CHANGED
|
@@ -98,7 +98,7 @@ describe GTA::Stage do
|
|
|
98
98
|
|
|
99
99
|
context "when using internally defined source object" do
|
|
100
100
|
it "sends the right git shell command" do
|
|
101
|
-
stage.should_receive(:sh).with("git push staging ci
|
|
101
|
+
stage.should_receive(:sh).with("git push staging ci:master")
|
|
102
102
|
stage.push
|
|
103
103
|
end
|
|
104
104
|
end
|
|
@@ -107,7 +107,7 @@ describe GTA::Stage do
|
|
|
107
107
|
let(:origin) { GTA::Stage.new('origin', manager, opts.merge('branch' => 'sendit')) }
|
|
108
108
|
|
|
109
109
|
it "sends the right git shell command" do
|
|
110
|
-
stage.should_receive(:sh).with("git push staging origin
|
|
110
|
+
stage.should_receive(:sh).with("git push staging origin:master")
|
|
111
111
|
stage.push(origin)
|
|
112
112
|
end
|
|
113
113
|
end
|
|
@@ -123,8 +123,10 @@ describe GTA::Stage do
|
|
|
123
123
|
|
|
124
124
|
context "when the source has a tag" do
|
|
125
125
|
let(:tag) { 'my-tag' }
|
|
126
|
+
let(:tag_finder) { double(newest: tag) }
|
|
126
127
|
|
|
127
128
|
it "uses the tag as the source reference" do
|
|
129
|
+
GTA::TagFinder.should_receive(:new).with(tag).and_return(tag_finder)
|
|
128
130
|
stage.should_receive(:sh).with("git push staging my-tag:master")
|
|
129
131
|
stage.push
|
|
130
132
|
end
|
|
@@ -132,7 +134,7 @@ describe GTA::Stage do
|
|
|
132
134
|
|
|
133
135
|
context "force push" do
|
|
134
136
|
it "adds the -f flag to the git command" do
|
|
135
|
-
stage.should_receive(:sh).with("git push -f staging ci
|
|
137
|
+
stage.should_receive(:sh).with("git push -f staging ci:master")
|
|
136
138
|
stage.force_push
|
|
137
139
|
end
|
|
138
140
|
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe GTA::TagFinder do
|
|
4
|
+
let(:finder) { GTA::TagFinder.new(tag)}
|
|
5
|
+
|
|
6
|
+
describe '#newest' do
|
|
7
|
+
context 'it receives a tag' do
|
|
8
|
+
let(:tag) { 'ci/*' }
|
|
9
|
+
before do
|
|
10
|
+
finder.stub(:`).and_return(git_response)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context 'we get a list from git' do
|
|
14
|
+
let(:git_response) {
|
|
15
|
+
"ci/12310\nci/12313\nci/29374"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
it 'should return the most recent one' do
|
|
19
|
+
finder.newest.should == "ci/29374"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context 'we get a single line from git' do
|
|
24
|
+
let(:git_response) {
|
|
25
|
+
"ci/29374"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
it 'should return it' do
|
|
29
|
+
finder.newest.should == "ci/29374"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context 'we get an empty string from git' do
|
|
34
|
+
let(:git_response) { "" }
|
|
35
|
+
|
|
36
|
+
it 'should be nil' do
|
|
37
|
+
finder.newest.should == nil
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context 'it receives nothing' do
|
|
43
|
+
let(:tag) { nil }
|
|
44
|
+
|
|
45
|
+
it "returns nothing" do
|
|
46
|
+
finder.newest.should == nil
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
metadata
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gta
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- socialchorus
|
|
8
8
|
- Kane Baccigalupi
|
|
9
|
+
- Ian Cooper
|
|
9
10
|
autorequire:
|
|
10
11
|
bindir: bin
|
|
11
12
|
cert_chain: []
|
|
12
|
-
date: 2013-07-
|
|
13
|
+
date: 2013-07-31 00:00:00.000000000 Z
|
|
13
14
|
dependencies:
|
|
14
15
|
- !ruby/object:Gem::Dependency
|
|
15
16
|
name: ansi
|
|
@@ -83,18 +84,31 @@ files:
|
|
|
83
84
|
- Rakefile
|
|
84
85
|
- gta.gemspec
|
|
85
86
|
- lib/gta.rb
|
|
87
|
+
- lib/gta/db.rb
|
|
88
|
+
- lib/gta/heroku_db.rb
|
|
89
|
+
- lib/gta/hotfix.rb
|
|
90
|
+
- lib/gta/local_db.rb
|
|
86
91
|
- lib/gta/manager.rb
|
|
87
|
-
- lib/gta/
|
|
92
|
+
- lib/gta/railtie.rb
|
|
88
93
|
- lib/gta/sh.rb
|
|
89
94
|
- lib/gta/stage.rb
|
|
95
|
+
- lib/gta/tag_finder.rb
|
|
90
96
|
- lib/gta/tasks.rb
|
|
91
97
|
- lib/gta/tasks/deploy.rake
|
|
92
98
|
- lib/gta/tasks/gta.rake
|
|
99
|
+
- lib/gta/tasks/heroku_db.rake
|
|
100
|
+
- lib/gta/tasks/hotfix.rake
|
|
93
101
|
- lib/gta/version.rb
|
|
102
|
+
- spec/db_spec.rb
|
|
103
|
+
- spec/fixtures/config/database.yml
|
|
94
104
|
- spec/fixtures/config/gta.yml
|
|
105
|
+
- spec/heroku_db_spec.rb
|
|
106
|
+
- spec/hotfix_spec.rb
|
|
107
|
+
- spec/local_db_spec.rb
|
|
95
108
|
- spec/manager_spec.rb
|
|
96
109
|
- spec/spec_helper.rb
|
|
97
110
|
- spec/stage_spec.rb
|
|
111
|
+
- spec/tag_finder_spec.rb
|
|
98
112
|
homepage: http://github.com/socialchorus/gta
|
|
99
113
|
licenses:
|
|
100
114
|
- MIT
|
|
@@ -121,7 +135,13 @@ specification_version: 4
|
|
|
121
135
|
summary: 'GTA: the Git Transit Authority - A git based deploy tool for moving code
|
|
122
136
|
from stage to stage.'
|
|
123
137
|
test_files:
|
|
138
|
+
- spec/db_spec.rb
|
|
139
|
+
- spec/fixtures/config/database.yml
|
|
124
140
|
- spec/fixtures/config/gta.yml
|
|
141
|
+
- spec/heroku_db_spec.rb
|
|
142
|
+
- spec/hotfix_spec.rb
|
|
143
|
+
- spec/local_db_spec.rb
|
|
125
144
|
- spec/manager_spec.rb
|
|
126
145
|
- spec/spec_helper.rb
|
|
127
146
|
- spec/stage_spec.rb
|
|
147
|
+
- spec/tag_finder_spec.rb
|
data/lib/gta/remote_db.rb
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module Remote
|
|
2
|
-
class DB
|
|
3
|
-
attr_reader :env, :app
|
|
4
|
-
|
|
5
|
-
def initialize(env, app)
|
|
6
|
-
raise "Environment not allowed" unless ['qa', 'staging'].include?(env)
|
|
7
|
-
@env = env
|
|
8
|
-
@app = app
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def reset
|
|
12
|
-
puts "==> RESETTING the #{app}-#{env} db..."
|
|
13
|
-
`heroku pg:reset DATABASE --app #{app}-#{env} --confirm #{app}-#{env}`
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def restore
|
|
17
|
-
puts "==> RESTORING #{app}-#{env} from latest backup..."
|
|
18
|
-
`heroku pgbackups:restore DATABASE_URL "#{DB::Config.db_url(app)}" --app #{app}-#{env} --confirm #{app}-#{env}`
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|