livebuzz-gitx 0.1.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 +7 -0
- data/.gitignore +31 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/Guardfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +84 -0
- data/Rakefile +5 -0
- data/bin/git-buildtag +6 -0
- data/bin/git-cleanup +7 -0
- data/bin/git-integrate +6 -0
- data/bin/git-nuke +6 -0
- data/bin/git-release +6 -0
- data/bin/git-review +6 -0
- data/bin/git-reviewrequest +8 -0
- data/bin/git-share +6 -0
- data/bin/git-start +6 -0
- data/bin/git-track +6 -0
- data/bin/git-update +6 -0
- data/lib/livebuzz/gitx/cli/base_command.rb +58 -0
- data/lib/livebuzz/gitx/cli/buildtag_command.rb +41 -0
- data/lib/livebuzz/gitx/cli/cleanup_command.rb +47 -0
- data/lib/livebuzz/gitx/cli/integrate_command.rb +95 -0
- data/lib/livebuzz/gitx/cli/nuke_command.rb +64 -0
- data/lib/livebuzz/gitx/cli/release_command.rb +41 -0
- data/lib/livebuzz/gitx/cli/review_command.rb +101 -0
- data/lib/livebuzz/gitx/cli/share_command.rb +17 -0
- data/lib/livebuzz/gitx/cli/start_command.rb +39 -0
- data/lib/livebuzz/gitx/cli/track_command.rb +16 -0
- data/lib/livebuzz/gitx/cli/update_command.rb +37 -0
- data/lib/livebuzz/gitx/configuration.rb +47 -0
- data/lib/livebuzz/gitx/extensions/string.rb +12 -0
- data/lib/livebuzz/gitx/extensions/thor.rb +39 -0
- data/lib/livebuzz/gitx/github.rb +177 -0
- data/lib/livebuzz/gitx/version.rb +5 -0
- data/lib/livebuzz/gitx.rb +10 -0
- data/livebuzz-gitx.gemspec +37 -0
- data/spec/fixtures/vcr_cassettes/pull_request_does_exist_with_failure_status.yml +135 -0
- data/spec/fixtures/vcr_cassettes/pull_request_does_exist_with_success_status.yml +149 -0
- data/spec/fixtures/vcr_cassettes/pull_request_does_not_exist.yml +133 -0
- data/spec/livebuzz/gitx/cli/base_command_spec.rb +41 -0
- data/spec/livebuzz/gitx/cli/buildtag_command_spec.rb +70 -0
- data/spec/livebuzz/gitx/cli/cleanup_command_spec.rb +37 -0
- data/spec/livebuzz/gitx/cli/integrate_command_spec.rb +272 -0
- data/spec/livebuzz/gitx/cli/nuke_command_spec.rb +165 -0
- data/spec/livebuzz/gitx/cli/release_command_spec.rb +148 -0
- data/spec/livebuzz/gitx/cli/review_command_spec.rb +307 -0
- data/spec/livebuzz/gitx/cli/share_command_spec.rb +32 -0
- data/spec/livebuzz/gitx/cli/start_command_spec.rb +96 -0
- data/spec/livebuzz/gitx/cli/track_command_spec.rb +31 -0
- data/spec/livebuzz/gitx/cli/update_command_spec.rb +79 -0
- data/spec/spec_helper.rb +86 -0
- data/spec/support/global_config.rb +24 -0
- data/spec/support/home_env.rb +11 -0
- data/spec/support/matchers/meet_expectations_matcher.rb +7 -0
- data/spec/support/pry.rb +1 -0
- data/spec/support/stub_execution.rb +14 -0
- data/spec/support/timecop.rb +9 -0
- data/spec/support/vcr.rb +6 -0
- data/spec/support/webmock.rb +1 -0
- metadata +350 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0616b6dbae3062ab6f77cd11e45b9d093347109e
|
4
|
+
data.tar.gz: 363feec0115bce1bc18baa4998c8be06e0556bcd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7d08cf9017d8b2a87190849657421a81bd86b423f31e492da77381456c17fc949e10c79715334ccbb54e2dabd11ca18960794135c633bad0650e7f7001294d8f
|
7
|
+
data.tar.gz: fcbbf1f9a923aa23e21c8b1c0691116fd3b39edd77e6d4636a8d79e2efaa9c8315900b70c3689f529c419b9cb9564ab04e300986739dd37c5e24dd68298d2ecc
|
data/.gitignore
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
## MAC OS
|
2
|
+
.DS_Store
|
3
|
+
|
4
|
+
## TEXTMATE
|
5
|
+
*.tmproj
|
6
|
+
tmtags
|
7
|
+
|
8
|
+
## EMACS
|
9
|
+
*~
|
10
|
+
\#*
|
11
|
+
.\#*
|
12
|
+
|
13
|
+
## VIM
|
14
|
+
*.swp
|
15
|
+
|
16
|
+
## GIT
|
17
|
+
*.orig
|
18
|
+
|
19
|
+
## PROJECT::GENERAL
|
20
|
+
coverage
|
21
|
+
rdoc
|
22
|
+
pkg
|
23
|
+
|
24
|
+
## bundler
|
25
|
+
Gemfile.lock
|
26
|
+
|
27
|
+
## RSpec temp files
|
28
|
+
spec/tmp
|
29
|
+
|
30
|
+
## RubyMine
|
31
|
+
/.idea/
|
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
livebuzz-gitx
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.2
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard :rspec, cmd: 'bundle exec rspec', failed_mode: :keep do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Ryan Sonnek
|
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,84 @@
|
|
1
|
+
# livebuzz-gitx
|
2
|
+
|
3
|
+
[](https://travis-ci.org/livebuzz/livebuzz-gitx)
|
4
|
+
[](https://coveralls.io/r/livebuzz/livebuzz-gitx)
|
5
|
+
[](https://codeclimate.com/github/livebuzz/livebuzz-gitx)
|
6
|
+
|
7
|
+
Useful Git eXtensions for Development workflow at LiveBuzz.
|
8
|
+
|
9
|
+
Forked from [TheGarage-GitX](https://github.com/thegarage/thegarage-gitx), which is inspired by the [socialcast-git-extensions gem](https://github.com/socialcast/socialcast-git-extensions)
|
10
|
+
|
11
|
+
# Git Extensions for Workflow
|
12
|
+
|
13
|
+
### Options
|
14
|
+
* `--trace` or `-v` = verbose output for debugging commands
|
15
|
+
* `--pretend` or `-p` = dry run commands and do not actually invoke operations
|
16
|
+
|
17
|
+
## git start <new_branch_name (optional)>
|
18
|
+
|
19
|
+
update local repository with latest upstream changes and create a new feature branch
|
20
|
+
|
21
|
+
## git update
|
22
|
+
|
23
|
+
update the local feature branch with latest remote changes plus upstream released changes.
|
24
|
+
|
25
|
+
## git integrate <aggregate_branch_name (optional, default: staging)>
|
26
|
+
|
27
|
+
integrate the current feature branch into an aggregate branch (ex: prototype, staging)
|
28
|
+
|
29
|
+
## git review
|
30
|
+
|
31
|
+
create a pull request on github for peer review of the current branch. This command is re-runnable
|
32
|
+
in order to re-assign pull requests.
|
33
|
+
|
34
|
+
options:
|
35
|
+
* `--assign` or `-a` = assign pull request to github user
|
36
|
+
* `--open` or `-o` = open pull request in default web browser.
|
37
|
+
* `--bump` or `-b` = bump an existing pull request by posting a comment to re-review new changes
|
38
|
+
* `--approve` = approve/signoff on pull request (with optional feedback)
|
39
|
+
* `--reject` = reject pull request (with details)
|
40
|
+
|
41
|
+
NOTE: the `--bump` option will also update the pull request commit status to mark the branch as 'pending peer review'.
|
42
|
+
This setting is cleared when a reviewer approves or rejects the pull request.
|
43
|
+
|
44
|
+
## git release
|
45
|
+
|
46
|
+
release the current feature branch to master. This operation will perform the following:
|
47
|
+
|
48
|
+
* pull in latest code from remote branch
|
49
|
+
* merge in latest code from master branch
|
50
|
+
* prompt user to confirm they actually want to perform the release
|
51
|
+
* merge current branch into master
|
52
|
+
* (optional) cleanup merged branches from remote server
|
53
|
+
|
54
|
+
options:
|
55
|
+
* `--cleanup` = automatically cleanup merged branches after release complete
|
56
|
+
|
57
|
+
# Extra Utility Git Extensions
|
58
|
+
|
59
|
+
## git cleanup
|
60
|
+
|
61
|
+
delete released branches after they have been merged into master.
|
62
|
+
|
63
|
+
## git nuke <aggregate_branch_name>
|
64
|
+
|
65
|
+
reset an aggregate branch (ex: prototype, staging) back to a known good state.
|
66
|
+
|
67
|
+
## git buildtag
|
68
|
+
|
69
|
+
create a build tag for the current Travis-CI build and push it back to origin
|
70
|
+
|
71
|
+
|
72
|
+
## Note on Patches/Pull Requests
|
73
|
+
|
74
|
+
* Fork the project.
|
75
|
+
* Make your feature addition or bug fix.
|
76
|
+
* Add tests for it. This is important so I don't break it in a
|
77
|
+
future version unintentionally.
|
78
|
+
* Commit, do not mess with rakefile, version, or history.
|
79
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
80
|
+
* Send me a pull request. Bonus points for topic branches.
|
81
|
+
|
82
|
+
## Copyright
|
83
|
+
|
84
|
+
Copyright (c) 2015 LiveBuzz Ltd. (c) 2013 The Garage, Inc. See LICENSE for details.
|
data/Rakefile
ADDED
data/bin/git-buildtag
ADDED
data/bin/git-cleanup
ADDED
data/bin/git-integrate
ADDED
data/bin/git-nuke
ADDED
data/bin/git-release
ADDED
data/bin/git-review
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
puts 'WARNING: git reviewrequest has been deprecated. use `git review` instead'
|
4
|
+
|
5
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
6
|
+
require 'livebuzz/gitx/cli/review_command'
|
7
|
+
args = ARGV.dup.unshift('review')
|
8
|
+
LiveBuzz::Gitx::Cli::ReviewCommand.start(args)
|
data/bin/git-share
ADDED
data/bin/git-start
ADDED
data/bin/git-track
ADDED
data/bin/git-update
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'pathname'
|
3
|
+
require 'rugged'
|
4
|
+
require 'livebuzz/gitx'
|
5
|
+
|
6
|
+
module LiveBuzz
|
7
|
+
module Gitx
|
8
|
+
module Cli
|
9
|
+
class BaseCommand < Thor
|
10
|
+
include Thor::Actions
|
11
|
+
|
12
|
+
class MergeError < Thor::Error; end
|
13
|
+
|
14
|
+
add_runtime_options!
|
15
|
+
|
16
|
+
method_option :trace, :type => :boolean, :aliases => '-v'
|
17
|
+
def initialize(*args)
|
18
|
+
super(*args)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def repo
|
24
|
+
@repo ||= begin
|
25
|
+
path = Dir.pwd
|
26
|
+
Rugged::Repository.discover(path)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def checkout_branch(branch_name)
|
31
|
+
run_cmd "git checkout #{branch_name}"
|
32
|
+
end
|
33
|
+
|
34
|
+
# lookup the current branch of the repo
|
35
|
+
def current_branch
|
36
|
+
repo.branches.find(&:head?)
|
37
|
+
end
|
38
|
+
|
39
|
+
def assert_aggregate_branch!(target_branch)
|
40
|
+
fail "Invalid aggregate branch: #{target_branch} must be one of supported aggregate branches #{config.aggregate_branches}" unless config.aggregate_branch?(target_branch)
|
41
|
+
end
|
42
|
+
|
43
|
+
def assert_not_protected_branch!(branch, action)
|
44
|
+
raise "Cannot #{action} reserved branch" if config.reserved_branch?(branch) || config.aggregate_branch?(branch)
|
45
|
+
end
|
46
|
+
|
47
|
+
# helper to invoke other CLI commands
|
48
|
+
def execute_command(command_class, method, args = [])
|
49
|
+
command_class.new.send(method, *args)
|
50
|
+
end
|
51
|
+
|
52
|
+
def config
|
53
|
+
@configuration ||= LiveBuzz::Gitx::Configuration.new(repo.workdir)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'livebuzz/gitx'
|
3
|
+
require 'livebuzz/gitx/cli/base_command'
|
4
|
+
|
5
|
+
module LiveBuzz
|
6
|
+
module Gitx
|
7
|
+
module Cli
|
8
|
+
class BuildtagCommand < BaseCommand
|
9
|
+
|
10
|
+
desc 'buildtag', 'create a tag for the current build and push it back to origin (supports Travis CI and Codeship)'
|
11
|
+
def buildtag
|
12
|
+
fail "Unknown branch. Environment variables TRAVIS_BRANCH or CI_BRANCH are required" unless branch_name
|
13
|
+
fail "Branch must be one of the supported taggable branches: #{config.taggable_branches}" unless config.taggable_branch?(branch_name)
|
14
|
+
|
15
|
+
label = "buildtag generated by build #{build_number}"
|
16
|
+
create_build_tag(branch_name, label)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# pull the current branch name from environment variables
|
22
|
+
# supports Travis CI or Codeship variables
|
23
|
+
# see https://www.codeship.io/documentation/continuous-integration/set-environment-variables/
|
24
|
+
def branch_name
|
25
|
+
ENV['TRAVIS_BRANCH'] || ENV['CI_BRANCH']
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_number
|
29
|
+
ENV['TRAVIS_BUILD_NUMBER'] || ENV['CI_BUILD_NUMBER']
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_build_tag(branch, label)
|
33
|
+
timestamp = Time.now.utc.strftime '%Y-%m-%d-%H-%M-%S'
|
34
|
+
git_tag = "build-#{branch}-#{timestamp}"
|
35
|
+
run_cmd "git tag #{git_tag} -a -m '#{label}'"
|
36
|
+
run_cmd "git push origin #{git_tag}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'livebuzz/gitx'
|
3
|
+
require 'livebuzz/gitx/cli/base_command'
|
4
|
+
|
5
|
+
module LiveBuzz
|
6
|
+
module Gitx
|
7
|
+
module Cli
|
8
|
+
class CleanupCommand < BaseCommand
|
9
|
+
desc 'cleanup', 'Cleanup branches that have been merged into master from the repo'
|
10
|
+
def cleanup
|
11
|
+
checkout_branch LiveBuzz::Gitx::BASE_BRANCH
|
12
|
+
run_cmd "git pull"
|
13
|
+
run_cmd 'git remote prune origin'
|
14
|
+
|
15
|
+
say "Deleting local and remote branches that have been merged into "
|
16
|
+
say LiveBuzz::Gitx::BASE_BRANCH, :green
|
17
|
+
merged_branches(remote: true).each do |branch|
|
18
|
+
run_cmd "git push origin --delete #{branch}"
|
19
|
+
end
|
20
|
+
merged_branches(remote: false).each do |branch|
|
21
|
+
run_cmd "git branch -d #{branch}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# @return list of branches that have been merged
|
28
|
+
def merged_branches(options = {})
|
29
|
+
args = []
|
30
|
+
args << '-r' if options[:remote]
|
31
|
+
args << "--merged"
|
32
|
+
output = run_cmd("git branch #{args.join(' ')}").split("\n")
|
33
|
+
branches = output.map do |branch|
|
34
|
+
branch = branch.gsub(/\*/, '').strip.split(' ').first
|
35
|
+
branch = branch.split('/').last if options[:remote]
|
36
|
+
branch
|
37
|
+
end
|
38
|
+
branches.uniq!
|
39
|
+
branches -= config.reserved_branches
|
40
|
+
branches.reject! { |b| config.aggregate_branch?(b) }
|
41
|
+
|
42
|
+
branches
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'livebuzz/gitx'
|
3
|
+
require 'livebuzz/gitx/cli/base_command'
|
4
|
+
require 'livebuzz/gitx/cli/update_command'
|
5
|
+
require 'livebuzz/gitx/github'
|
6
|
+
|
7
|
+
module LiveBuzz
|
8
|
+
module Gitx
|
9
|
+
module Cli
|
10
|
+
class IntegrateCommand < BaseCommand
|
11
|
+
include LiveBuzz::Gitx::Github
|
12
|
+
desc 'integrate', 'integrate the current branch into one of the aggregate development branches (default = staging)'
|
13
|
+
method_option :resume, :type => :string, :aliases => '-r', :desc => 'resume merging of feature-branch'
|
14
|
+
def integrate(integration_branch = 'staging')
|
15
|
+
assert_aggregate_branch!(integration_branch)
|
16
|
+
|
17
|
+
branch = feature_branch_name
|
18
|
+
print_message(branch, integration_branch)
|
19
|
+
|
20
|
+
begin
|
21
|
+
execute_command(UpdateCommand, :update)
|
22
|
+
rescue
|
23
|
+
fail MergeError, "Merge Conflict Occurred. Please Merge Conflict Occurred. Please fix merge conflict and rerun the integrate command"
|
24
|
+
end
|
25
|
+
|
26
|
+
integrate_branch(branch, integration_branch) unless options[:resume]
|
27
|
+
checkout_branch branch
|
28
|
+
|
29
|
+
create_integrate_comment(branch) unless config.reserved_branch?(branch)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def print_message(branch, integration_branch)
|
35
|
+
message = options[:resume] ? 'Resuming integration of' : 'Integrating'
|
36
|
+
say "#{message} "
|
37
|
+
say "#{branch} ", :green
|
38
|
+
say "into "
|
39
|
+
say integration_branch, :green
|
40
|
+
end
|
41
|
+
|
42
|
+
def integrate_branch(branch, integration_branch)
|
43
|
+
fetch_remote_branch(integration_branch)
|
44
|
+
begin
|
45
|
+
run_cmd "git merge #{branch}"
|
46
|
+
rescue
|
47
|
+
fail MergeError, "Merge Conflict Occurred. Please fix merge conflict and rerun command with --resume #{branch} flag"
|
48
|
+
end
|
49
|
+
run_cmd "git push origin HEAD"
|
50
|
+
end
|
51
|
+
|
52
|
+
def feature_branch_name
|
53
|
+
@feature_branch ||= begin
|
54
|
+
feature_branch = options[:resume] || current_branch.name
|
55
|
+
until local_branch_exists?(feature_branch)
|
56
|
+
feature_branch = ask("#{feature_branch} does not exist. Please select one of the available local branches: #{local_branches}")
|
57
|
+
end
|
58
|
+
feature_branch
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# nuke local branch and pull fresh version from remote repo
|
63
|
+
def fetch_remote_branch(target_branch)
|
64
|
+
create_remote_branch(target_branch) unless remote_branch_exists?(target_branch)
|
65
|
+
run_cmd "git fetch origin"
|
66
|
+
run_cmd "git branch -D #{target_branch}", :allow_failure => true
|
67
|
+
checkout_branch target_branch
|
68
|
+
end
|
69
|
+
|
70
|
+
def local_branch_exists?(branch)
|
71
|
+
local_branches.include?(branch)
|
72
|
+
end
|
73
|
+
|
74
|
+
def local_branches
|
75
|
+
@local_branches ||= repo.branches.each_name(:local)
|
76
|
+
end
|
77
|
+
|
78
|
+
def remote_branch_exists?(target_branch)
|
79
|
+
repo.branches.each_name(:remote).include?("origin/#{target_branch}")
|
80
|
+
end
|
81
|
+
|
82
|
+
def create_remote_branch(target_branch)
|
83
|
+
repo.create_branch(target_branch, LiveBuzz::Gitx::BASE_BRANCH)
|
84
|
+
run_cmd "git push origin #{target_branch}:#{target_branch}"
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_integrate_comment(branch)
|
88
|
+
pull_request = find_or_create_pull_request(branch)
|
89
|
+
comment = '[gitx] integrated into staging :twisted_rightwards_arrows:'
|
90
|
+
github_client.add_comment(github_slug, pull_request.number, comment)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'livebuzz/gitx'
|
3
|
+
require 'livebuzz/gitx/cli/base_command'
|
4
|
+
|
5
|
+
module LiveBuzz
|
6
|
+
module Gitx
|
7
|
+
module Cli
|
8
|
+
class NukeCommand < BaseCommand
|
9
|
+
desc 'nuke', 'nuke the specified aggregate branch and reset it to a known good state'
|
10
|
+
method_option :destination, :type => :string, :aliases => '-d', :desc => 'destination branch to reset to'
|
11
|
+
def nuke(bad_branch)
|
12
|
+
good_branch = options[:destination] || ask("What branch do you want to reset #{bad_branch} to? (default: #{bad_branch})")
|
13
|
+
good_branch = bad_branch if good_branch.length == 0
|
14
|
+
|
15
|
+
last_known_good_tag = current_build_tag(good_branch)
|
16
|
+
return unless yes?("Reset #{bad_branch} to #{last_known_good_tag}? (y/n)", :green)
|
17
|
+
assert_aggregate_branch!(bad_branch)
|
18
|
+
return if migrations_need_to_be_reverted?(bad_branch, last_known_good_tag)
|
19
|
+
|
20
|
+
say "Resetting "
|
21
|
+
say "#{bad_branch} ", :green
|
22
|
+
say "branch to "
|
23
|
+
say last_known_good_tag, :green
|
24
|
+
|
25
|
+
checkout_branch LiveBuzz::Gitx::BASE_BRANCH
|
26
|
+
run_cmd "git branch -D #{bad_branch}", :allow_failure => true
|
27
|
+
run_cmd "git push origin --delete #{bad_branch}", :allow_failure => true
|
28
|
+
run_cmd "git checkout -b #{bad_branch} #{last_known_good_tag}"
|
29
|
+
run_cmd "git push origin #{bad_branch}"
|
30
|
+
run_cmd "git branch --set-upstream-to origin/#{bad_branch}"
|
31
|
+
checkout_branch LiveBuzz::Gitx::BASE_BRANCH
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def migrations_need_to_be_reverted?(bad_branch, last_known_good_tag)
|
37
|
+
return false unless File.exist?('db/migrate')
|
38
|
+
outdated_migrations = run_cmd("git diff #{last_known_good_tag}...#{bad_branch} --name-only db/migrate").split
|
39
|
+
return false if outdated_migrations.empty?
|
40
|
+
|
41
|
+
say "#{bad_branch} contains migrations that may need to be reverted. Ensure any reversable migrations are reverted on affected databases before nuking.", :red
|
42
|
+
say 'Example commands to revert outdated migrations:'
|
43
|
+
outdated_migrations.reverse.each do |migration|
|
44
|
+
version = File.basename(migration).split('_').first
|
45
|
+
say "rake db:migrate:down VERSION=#{version}"
|
46
|
+
end
|
47
|
+
!yes?("Are you sure you want to nuke #{bad_branch}? (y/n) ", :green)
|
48
|
+
end
|
49
|
+
|
50
|
+
def current_build_tag(branch)
|
51
|
+
last_build_tag = build_tags_for_branch(branch).last
|
52
|
+
raise "No known good tag found for branch: #{branch}. Verify tag exists via `git tag -l 'build-#{branch}-*'`" unless last_build_tag
|
53
|
+
last_build_tag
|
54
|
+
end
|
55
|
+
|
56
|
+
def build_tags_for_branch(branch)
|
57
|
+
run_cmd "git fetch --tags"
|
58
|
+
build_tags = run_cmd("git tag -l 'build-#{branch}-*'").split
|
59
|
+
build_tags.sort
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'livebuzz/gitx'
|
3
|
+
require 'livebuzz/gitx/cli/base_command'
|
4
|
+
require 'livebuzz/gitx/cli/update_command'
|
5
|
+
require 'livebuzz/gitx/cli/integrate_command'
|
6
|
+
require 'livebuzz/gitx/cli/cleanup_command'
|
7
|
+
require 'livebuzz/gitx/github'
|
8
|
+
|
9
|
+
module LiveBuzz
|
10
|
+
module Gitx
|
11
|
+
module Cli
|
12
|
+
class ReleaseCommand < BaseCommand
|
13
|
+
include LiveBuzz::Gitx::Github
|
14
|
+
|
15
|
+
desc 'release', 'release the current branch to production'
|
16
|
+
method_option :cleanup, :type => :boolean, :desc => 'cleanup merged branches after release'
|
17
|
+
def release
|
18
|
+
return unless yes?("Release #{current_branch.name} to production? (y/n)", :green)
|
19
|
+
|
20
|
+
branch = current_branch.name
|
21
|
+
assert_not_protected_branch!(branch, 'release')
|
22
|
+
execute_command(UpdateCommand, :update)
|
23
|
+
|
24
|
+
find_or_create_pull_request(branch)
|
25
|
+
status = branch_status(branch)
|
26
|
+
if status != 'success'
|
27
|
+
return unless yes?("Branch status is currently: #{status}. Proceed with release? (y/n)", :red)
|
28
|
+
end
|
29
|
+
|
30
|
+
checkout_branch LiveBuzz::Gitx::BASE_BRANCH
|
31
|
+
run_cmd "git pull origin #{LiveBuzz::Gitx::BASE_BRANCH}"
|
32
|
+
run_cmd "git merge --no-ff #{branch}"
|
33
|
+
run_cmd "git push origin HEAD"
|
34
|
+
|
35
|
+
execute_command(IntegrateCommand, :integrate, 'staging')
|
36
|
+
execute_command(CleanupCommand, :cleanup) if options[:cleanup]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|