gta 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 27c920a2a56f8e301489d77634ce463854a5ffa1
4
+ data.tar.gz: f548a008605b16f83c651681d97f70447cc3e80d
5
+ SHA512:
6
+ metadata.gz: 25f6527c6ddc4a6a9165a62a87fe2d5857bf07a959889daa5055b2a780f16cade8384f8ab642c84ef03a2b029a5480872b9c59420d6bccbf325d4c3d8041844b
7
+ data.tar.gz: 76dc5ee7aebea7764d994cf3b53f4efac5f9d5ddd185c061fba665c90b70d87d20e7009f0959ce089aa3460f645138af61311f5c24b0e10f1eee8578ef74904f
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rvmrc ADDED
@@ -0,0 +1,6 @@
1
+ rvm_install_on_use_flag=1
2
+ rvm_trust_rvmrcs_flag=1
3
+ rvm_gemset_create_on_use_flag=1
4
+
5
+ rvm use 2.0.0@gta --create
6
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gta.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 socialchorus
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.
@@ -0,0 +1,42 @@
1
+ # GTA - the Git Transit Authority
2
+
3
+ GTA is a git-based deploy tool for moving code from stage to stage.
4
+
5
+ Heroku has made git deploys an awesome standard. Mislav's git-deploy gem
6
+ has made this ease of deploy a possibility for servers that are not
7
+ Heroku too. Despite the easiness of a git deploy system managing a
8
+ series of stages, ie. origin => ci => staging => production, takes some
9
+ care and consideration. Additionally, hotfixing changes in the middle of
10
+ the chain causes a reordering of commits and different push proceedures
11
+ that can car reek havok.
12
+
13
+ GTA reads git configuration from yml file that should be checked into
14
+ source control, assuring the whole team is sharing configurations. There
15
+ are easy methods for setting up git remotes, and moving code from stage
16
+ to stage.
17
+
18
+ ## Installation
19
+
20
+ Add this line to your application's Gemfile:
21
+
22
+ gem 'gta'
23
+
24
+ And then execute:
25
+
26
+ $ bundle
27
+
28
+ Or install it yourself as:
29
+
30
+ $ gem install gta
31
+
32
+ ## Usage
33
+
34
+ Rake tasks are in progress; stay tuned.
35
+
36
+ ## Contributing
37
+
38
+ 1. Fork it
39
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
40
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
41
+ 4. Push to the branch (`git push origin my-new-feature`)
42
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'gta/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "gta"
8
+ spec.version = GTA::VERSION
9
+ spec.authors = ["socialchorus", "Kane Baccigalupi"]
10
+ spec.email = ["developers@socialchorus.com"]
11
+ spec.description = %q{GTA: the Git Transit Authority - A git based deploy tool for moving code from stage to stage.}
12
+ spec.summary = %q{GTA: the Git Transit Authority - A git based deploy tool for moving code from stage to stage.}
13
+ spec.homepage = "http://github.com/socialchorus/gta"
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_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ end
@@ -0,0 +1,4 @@
1
+ require "gta/version"
2
+ require "gta/sh"
3
+ require "gta/manager"
4
+ require "gta/stage"
@@ -0,0 +1,37 @@
1
+ module GTA
2
+ class Manager
3
+ attr_reader :config_path
4
+
5
+ def initialize(config_path = "#{Dir.pwd}/config/gta.yml")
6
+ @config_path = config_path
7
+ end
8
+
9
+ def config
10
+ @config ||= YAML.load(File.read(config_path))
11
+ end
12
+
13
+ def stages
14
+ @stages ||= config.map{ |name, opts| Stage.new(name, self, opts) }
15
+ end
16
+
17
+ def stage(name)
18
+ stages.detect{|s| s.name == name.to_s}
19
+ end
20
+
21
+ def stage!(name)
22
+ stage(name) || (raise ArgumentError.new("Stage #{name} not found"))
23
+ end
24
+
25
+ def push_to(name)
26
+ stage!(name).push
27
+ end
28
+
29
+ def fetch
30
+ stages.each(&:fetch)
31
+ end
32
+
33
+ def setup
34
+ stages.each(&:add_remote)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,22 @@
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
+
@@ -0,0 +1,7 @@
1
+ module GTA
2
+ module Sh
3
+ def sh(command)
4
+ system(command)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,64 @@
1
+ module GTA
2
+ class Stage
3
+ include Sh
4
+
5
+ attr_reader :name, :repository, :source_name, :branch, :tag, :manager
6
+
7
+ def initialize(name, manager, opts)
8
+ @name = name
9
+ @manager = manager
10
+ @repository = opts['repository']
11
+ @source_name = opts['source']
12
+ @branch = opts['branch'] || 'master'
13
+ @tag = opts['tag']
14
+ end
15
+
16
+ def stages
17
+ manager.stages
18
+ end
19
+
20
+ def source
21
+ @source ||= manager.stage!(source_name)
22
+ end
23
+
24
+ def add_remote
25
+ raise "no name defined for #{self}" unless name
26
+ raise "no repository defined for #{name}" unless repository
27
+
28
+ sh "git remote add #{name} #{repository}"
29
+ end
30
+
31
+ def push(s=source, forced=nil)
32
+ sh push_command(source_from(s), forced)
33
+ end
34
+
35
+ def force_push(s=source)
36
+ sh push_command(source_from(s), :force)
37
+ end
38
+
39
+ def fetch
40
+ sh "git fetch #{name}"
41
+ end
42
+
43
+ def ==(other)
44
+ name == other.name &&
45
+ branch == other.branch &&
46
+ tag == other.tag
47
+ end
48
+
49
+ # -----------
50
+
51
+ def source_from(s)
52
+ s.respond_to?(:source_ref) ? s.source_ref : s
53
+ end
54
+
55
+ def source_ref
56
+ tag || "#{name}/#{branch}"
57
+ end
58
+
59
+ def push_command(source_ref, forced=nil)
60
+ force = forced == :force ? " -f" : ""
61
+ "git push#{force} #{name} #{source_ref}:#{branch}"
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,3 @@
1
+ module GTA
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,15 @@
1
+ ci:
2
+ repository: git@github.com:socialchorus/activator.git
3
+
4
+ staging:
5
+ source_stage: ci
6
+ tag: staging/*
7
+ repository: git@heroku.com:activator-staging.git
8
+
9
+ qa:
10
+ source_stage: staging
11
+ repository: git@heroku.com:activator-qa.git
12
+
13
+ production:
14
+ source_stage: qa
15
+ repository: git@heroku.com:activator-production.git
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe GTA::Manager do
4
+ let(:config_path) { File.dirname(__FILE__) + "/fixtures/config/gta.yml" }
5
+ let(:manager) { GTA::Manager.new(config_path) }
6
+
7
+ it "builds stages for each entry in the yml" do
8
+ manager.stages.size.should == 4
9
+ manager.stages.map(&:class).uniq.should == [GTA::Stage]
10
+ end
11
+
12
+ describe '#fetch' do
13
+ it "loops through each stage and calls fetch" do
14
+ manager.stages.each do |stage|
15
+ stage.should_receive(:fetch)
16
+ end
17
+ manager.fetch
18
+ end
19
+ end
20
+
21
+ describe '#stage' do
22
+ it "finds the right stage by name" do
23
+ manager.stage('qa').should be_a(GTA::Stage)
24
+ manager.stage(:qa).name.should == 'qa'
25
+ end
26
+ end
27
+
28
+ describe '#stage!' do
29
+ it 'raises an error if it cannot find the right stage' do
30
+ expect {
31
+ manager.stage!(:foo)
32
+ }.to raise_error
33
+ end
34
+
35
+ it 'finds and return the right stage otherwise' do
36
+ manager.stage!(:ci).should be_a(GTA::Stage)
37
+ end
38
+ end
39
+
40
+ describe '#push_to' do
41
+ it "tells the right stage to push itself" do
42
+ manager.stage(:qa).should_receive(:push)
43
+ manager.push_to(:qa)
44
+ end
45
+ end
46
+
47
+ describe '#setup' do
48
+ it 'adds a remote for each stage' do
49
+ manager.stages.each do |stage|
50
+ stage.should_receive(:add_remote)
51
+ end
52
+ manager.setup
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,8 @@
1
+ here = File.dirname(__FILE__)
2
+
3
+ require "#{here}/../lib/gta"
4
+ Dir["#{here}/support/**/*.rb"].each {|f| require f}
5
+
6
+ RSpec.configure do |config|
7
+ config.color_enabled = true
8
+ end
@@ -0,0 +1,133 @@
1
+ require 'spec_helper'
2
+
3
+ describe GTA::Stage do
4
+ let(:tag) { nil }
5
+ let(:branch) { nil }
6
+ let(:repository) { "git@github.com:socialchorus/activator.git" }
7
+ let(:opts) {
8
+ {
9
+ "source" => "ci",
10
+ "repository" => repository,
11
+ "tag" => tag,
12
+ "branch" => branch
13
+ }
14
+ }
15
+ let(:stage) { GTA::Stage.new('staging', manager, opts) }
16
+ let(:source) { GTA::Stage.new('ci', manager, opts.merge('source' => 'origin')) }
17
+ let(:manager) { double('manager') }
18
+
19
+ before do
20
+ manager.stub(:stage!).and_return(source)
21
+ stage.stub(:sh)
22
+ end
23
+
24
+ describe 'initalization' do
25
+ it "has a name" do
26
+ stage.name.should == 'staging'
27
+ end
28
+
29
+ it "stores the repository" do
30
+ stage.repository.should == 'git@github.com:socialchorus/activator.git'
31
+ end
32
+
33
+ it "stores the intended source stage" do
34
+ stage.source_name.should == 'ci'
35
+ end
36
+
37
+ it "creates a default branch" do
38
+ stage.branch.should == 'master'
39
+ end
40
+ end
41
+
42
+ describe '#fetch' do
43
+ it "calls the right git command" do
44
+ stage.should_receive(:sh).with("git fetch staging")
45
+ stage.fetch
46
+ end
47
+ end
48
+
49
+ describe '#source' do
50
+ it "gets the source based on the source name" do
51
+ stage.source.should == source
52
+ end
53
+ end
54
+
55
+ describe '#add_remote' do
56
+ context 'when the repository is nil' do
57
+ let(:repository) { nil }
58
+
59
+ it "should raise an error" do
60
+ expect {
61
+ stage.add_remote
62
+ }.to raise_error
63
+ end
64
+ end
65
+
66
+ context 'when all is good' do
67
+ it "should call #sh with the right git command if there is a repository" do
68
+ stage.should_receive(:sh).with("git remote add staging #{repository}")
69
+ stage.add_remote
70
+ end
71
+ end
72
+ end
73
+
74
+ describe '#push' do
75
+ # private ... delete tests after #push fully tested
76
+ describe '#push_command' do
77
+ context "without a tag and branch is default" do
78
+ it "should be a string that allows the interpolation of the source" do
79
+ stage.push_command('source').should == 'git push staging source:master'
80
+ end
81
+ end
82
+
83
+ context "with an alternate branch" do
84
+ let(:branch) { 'alt' }
85
+
86
+ it "should push to the other branch instead" do
87
+ stage.push_command('source').should == 'git push staging source:alt'
88
+ end
89
+ end
90
+ end
91
+
92
+ context "when using internally defined source object" do
93
+ it "sends the right git shell command" do
94
+ stage.should_receive(:sh).with("git push staging ci/master:master")
95
+ stage.push
96
+ end
97
+ end
98
+
99
+ context "when passed an alternative source object" do
100
+ let(:origin) { GTA::Stage.new('origin', manager, opts.merge('branch' => 'sendit')) }
101
+
102
+ it "sends the right git shell command" do
103
+ stage.should_receive(:sh).with("git push staging origin/sendit:master")
104
+ stage.push(origin)
105
+ end
106
+ end
107
+
108
+ context "when passed a string identifying the source (and an alt branch)" do
109
+ let(:branch) { 'alt_branch' }
110
+
111
+ it "sends the right git shell command" do
112
+ stage.should_receive(:sh).with("git push staging foo:alt_branch")
113
+ stage.push('foo')
114
+ end
115
+ end
116
+
117
+ context "when the source has a tag" do
118
+ let(:tag) { 'my-tag' }
119
+
120
+ it "uses the tag as the source reference" do
121
+ stage.should_receive(:sh).with("git push staging my-tag:master")
122
+ stage.push
123
+ end
124
+ end
125
+
126
+ context "force push" do
127
+ it "adds the -f flag to the git command" do
128
+ stage.should_receive(:sh).with("git push -f staging ci/master:master")
129
+ stage.force_push
130
+ end
131
+ end
132
+ end
133
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gta
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - socialchorus
8
+ - Kane Baccigalupi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: '1.3'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: '1.3'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ description: 'GTA: the Git Transit Authority - A git based deploy tool for moving
57
+ code from stage to stage.'
58
+ email:
59
+ - developers@socialchorus.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - .gitignore
65
+ - .rvmrc
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - gta.gemspec
71
+ - lib/gta.rb
72
+ - lib/gta/manager.rb
73
+ - lib/gta/remote_db.rb
74
+ - lib/gta/sh.rb
75
+ - lib/gta/stage.rb
76
+ - lib/gta/version.rb
77
+ - spec/fixtures/config/gta.yml
78
+ - spec/manager_spec.rb
79
+ - spec/spec_helper.rb
80
+ - spec/stage_spec.rb
81
+ homepage: http://github.com/socialchorus/gta
82
+ licenses:
83
+ - MIT
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 2.0.3
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: 'GTA: the Git Transit Authority - A git based deploy tool for moving code
105
+ from stage to stage.'
106
+ test_files:
107
+ - spec/fixtures/config/gta.yml
108
+ - spec/manager_spec.rb
109
+ - spec/spec_helper.rb
110
+ - spec/stage_spec.rb