gta 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.
@@ -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