flash_flow 1.5.3 → 1.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8d3235b782d5313f27539dade0300a599ba7b470
4
- data.tar.gz: ef51a03ff49f19a7a3bd7c25033e3290a2bccf84
3
+ metadata.gz: d6ebf90cccffeac908c0d843e1b41ecda291b996
4
+ data.tar.gz: dafdf83630955c37b97a715653cf43c2f560cd96
5
5
  SHA512:
6
- metadata.gz: 0034d2b3b5185dab753fb866be335e853a43488d4f73b7da35fb8e7f084c4f3e90be1bf160dc8715eb2e690b2011d407986615e6b24ae35210f0dbf2c54bb573
7
- data.tar.gz: 989d8f49405a254f09cd20963b98417109eb08e4e1f4e8c21a7879efaa683a61b46589bb7ad057a3a7214cc1d692d3dbafe361f528a8d147492ba8ae04d214f3
6
+ metadata.gz: 4b705feb54f7c4e126129541ec072b75a75da229c74b9ca89b8da7f4a7defdb3cb9ab45acffce4905aee915e819c9bb33be0a3d48571e8ccc7a60b8aba8b6958
7
+ data.tar.gz: 0a3433d37f0e5158af98313741bb84e5bd3116a83c14fb6d066248dcbcf2ab594716598abab456f9e8cb3986e04aba138aaae36e288712ea461d5ff0cf4942c5
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.3.1
1
+ 2.3.4
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in fund_america.gemspec
4
3
  gemspec
data/Gemfile.lock CHANGED
@@ -1,135 +1,145 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- flash_flow (1.5.2)
4
+ flash_flow (1.6.0)
5
5
  google-api-client
6
- hipchat (~> 1.5)
7
6
  mail
8
7
  octokit (~> 4.1)
9
8
  percy-client
10
9
  pivotal-tracker (~> 0.5)
11
10
  prawn
12
11
  ruby-graphviz (> 0)
12
+ tb-bjb (~> 1.6)
13
13
 
14
14
  GEM
15
15
  remote: https://rubygems.org/
16
16
  specs:
17
- addressable (2.4.0)
18
- builder (3.2.2)
19
- byebug (3.5.1)
20
- columnize (~> 0.8)
21
- debugger-linecache (~> 1.2)
22
- slop (~> 3.6)
23
- columnize (0.9.0)
17
+ activemodel (5.2.2)
18
+ activesupport (= 5.2.2)
19
+ activesupport (5.2.2)
20
+ concurrent-ruby (~> 1.0, >= 1.0.2)
21
+ i18n (>= 0.7, < 2)
22
+ minitest (~> 5.1)
23
+ tzinfo (~> 1.1)
24
+ addressable (2.5.2)
25
+ public_suffix (>= 2.0.2, < 4.0)
26
+ builder (3.2.3)
27
+ concurrent-ruby (1.1.3)
24
28
  crack (0.4.3)
25
29
  safe_yaml (~> 1.0.0)
26
- debugger-linecache (1.2.0)
27
- domain_name (0.5.20161129)
30
+ declarative (0.0.10)
31
+ declarative-option (0.1.0)
32
+ domain_name (0.5.20180417)
28
33
  unf (>= 0.0.5, < 1.0.0)
29
- faraday (0.9.2)
34
+ excon (0.62.0)
35
+ faraday (0.15.4)
30
36
  multipart-post (>= 1.2, < 3)
31
- google-api-client (0.9.12)
32
- addressable (~> 2.3)
33
- googleauth (~> 0.5)
34
- httpclient (~> 2.7)
35
- hurley (~> 0.1)
36
- memoist (~> 0.11)
37
- mime-types (>= 1.6)
38
- representable (~> 2.3.0)
39
- retriable (~> 2.0)
40
- thor (~> 0.19)
41
- googleauth (0.5.1)
42
- faraday (~> 0.9)
43
- jwt (~> 1.4)
44
- logging (~> 2.0)
45
- memoist (~> 0.12)
37
+ faraday-http-cache (1.3.1)
38
+ faraday (~> 0.8)
39
+ faraday_middleware (0.12.2)
40
+ faraday (>= 0.7.4, < 1.0)
41
+ google-api-client (0.26.0)
42
+ addressable (~> 2.5, >= 2.5.1)
43
+ googleauth (>= 0.5, < 0.8.0)
44
+ httpclient (>= 2.8.1, < 3.0)
45
+ mime-types (~> 3.0)
46
+ representable (~> 3.0)
47
+ retriable (>= 2.0, < 4.0)
48
+ signet (~> 0.10)
49
+ googleauth (0.7.1)
50
+ faraday (~> 0.12)
51
+ jwt (>= 1.4, < 3.0)
52
+ memoist (~> 0.16)
46
53
  multi_json (~> 1.11)
47
- os (~> 0.9)
54
+ os (>= 0.9, < 2.0)
48
55
  signet (~> 0.7)
49
- hipchat (1.5.4)
50
- httparty
51
- mimemagic
52
- http-cookie (1.0.2)
56
+ http-cookie (1.0.3)
53
57
  domain_name (~> 0.5)
54
- httparty (0.14.0)
55
- multi_xml (>= 0.5.2)
56
58
  httpclient (2.8.3)
57
- hurley (0.2)
58
- jwt (1.5.6)
59
- little-plugger (1.1.4)
60
- logging (2.1.0)
61
- little-plugger (~> 1.1)
62
- multi_json (~> 1.10)
63
- mail (2.6.4)
64
- mime-types (>= 1.16, < 4)
65
- memoist (0.15.0)
66
- mime-types (3.1)
59
+ i18n (1.2.0)
60
+ concurrent-ruby (~> 1.0)
61
+ jwt (2.1.0)
62
+ mail (2.7.1)
63
+ mini_mime (>= 0.1.1)
64
+ memoist (0.16.0)
65
+ mime-types (3.2.2)
67
66
  mime-types-data (~> 3.2015)
68
- mime-types-data (3.2016.0521)
69
- mimemagic (0.3.2)
70
- mini_portile2 (2.1.0)
67
+ mime-types-data (3.2018.0812)
68
+ mini_mime (1.0.1)
69
+ mini_portile2 (2.3.0)
71
70
  minitest (5.3.5)
72
71
  minitest-stub_any_instance (1.0.1)
73
- multi_json (1.12.1)
74
- multi_xml (0.6.0)
72
+ multi_json (1.13.1)
75
73
  multipart-post (2.0.0)
76
74
  netrc (0.11.0)
77
- nokogiri (1.7.0.1)
78
- mini_portile2 (~> 2.1.0)
79
- nokogiri-happymapper (0.5.9)
75
+ nokogiri (1.8.5)
76
+ mini_portile2 (~> 2.3.0)
77
+ nokogiri-happymapper (0.8.0)
80
78
  nokogiri (~> 1.5)
81
- octokit (4.3.0)
82
- sawyer (~> 0.7.0, >= 0.5.3)
83
- os (0.9.6)
84
- pdf-core (0.6.1)
85
- percy-client (1.9.0)
79
+ octokit (4.13.0)
80
+ sawyer (~> 0.8.0, >= 0.5.3)
81
+ os (1.0.0)
82
+ pdf-core (0.7.0)
83
+ percy-client (2.0.1)
84
+ addressable
85
+ excon
86
86
  faraday (>= 0.9)
87
- httpclient (>= 2.6)
88
87
  pivotal-tracker (0.5.13)
89
88
  builder
90
89
  crack
91
90
  nokogiri (>= 1.5.5)
92
91
  nokogiri-happymapper (>= 0.5.4)
93
92
  rest-client (>= 1.8.0)
94
- prawn (2.1.0)
95
- pdf-core (~> 0.6.1)
96
- ttfunk (~> 1.4.0)
93
+ prawn (2.2.2)
94
+ pdf-core (~> 0.7.0)
95
+ ttfunk (~> 1.5)
96
+ public_suffix (3.0.3)
97
97
  rake (10.4.2)
98
- representable (2.3.0)
99
- uber (~> 0.0.7)
100
- rest-client (2.0.0)
98
+ representable (3.0.4)
99
+ declarative (< 0.1.0)
100
+ declarative-option (< 0.2.0)
101
+ uber (< 0.2.0)
102
+ rest-client (2.0.2)
101
103
  http-cookie (>= 1.0.2, < 2.0)
102
104
  mime-types (>= 1.16, < 4.0)
103
105
  netrc (~> 0.8)
104
- retriable (2.1.0)
105
- ruby-graphviz (1.2.2)
106
+ retriable (3.1.2)
107
+ ruby-graphviz (1.2.4)
106
108
  safe_yaml (1.0.4)
107
- sawyer (0.7.0)
108
- addressable (>= 2.3.5, < 2.5)
109
- faraday (~> 0.8, < 0.10)
110
- signet (0.7.3)
109
+ sawyer (0.8.1)
110
+ addressable (>= 2.3.5, < 2.6)
111
+ faraday (~> 0.8, < 1.0)
112
+ signet (0.11.0)
111
113
  addressable (~> 2.3)
112
114
  faraday (~> 0.9)
113
- jwt (~> 1.5)
115
+ jwt (>= 1.5, < 3.0)
114
116
  multi_json (~> 1.10)
115
- slop (3.6.0)
116
- thor (0.19.1)
117
- ttfunk (1.4.0)
118
- uber (0.0.15)
117
+ simple_oauth (0.3.1)
118
+ tb-bjb (1.6.1)
119
+ activemodel (>= 4.1.6)
120
+ activesupport (>= 4.1.6)
121
+ faraday (~> 0.9)
122
+ faraday-http-cache (~> 1.2)
123
+ faraday_middleware (~> 0.10)
124
+ simple_oauth (~> 0.3)
125
+ thread_safe (0.3.6)
126
+ ttfunk (1.5.1)
127
+ tzinfo (1.2.5)
128
+ thread_safe (~> 0.1)
129
+ uber (0.1.0)
119
130
  unf (0.1.4)
120
131
  unf_ext
121
- unf_ext (0.0.7.2)
132
+ unf_ext (0.0.7.5)
122
133
 
123
134
  PLATFORMS
124
135
  ruby
125
136
 
126
137
  DEPENDENCIES
127
138
  bundler (~> 1.6)
128
- byebug (> 0)
129
139
  flash_flow!
130
140
  minitest (> 0)
131
141
  minitest-stub_any_instance (> 0)
132
142
  rake (> 0)
133
143
 
134
144
  BUNDLED WITH
135
- 1.14.3
145
+ 1.17.1
data/README.md CHANGED
@@ -82,11 +82,6 @@ In addition, as part of our production deploy script, we run `flash_flow --prod-
82
82
  that are newly in the `master_branch` and adds a comment "Deployed to production on 12/25/2015 at 11:11pm". Tracker
83
83
  doesn't support a real state for "In production", so for us this comment serves as that state.
84
84
 
85
- ### Configuring hipchat
86
- When a branch other than the one you're on doesn't merge cleanly and can't be fixed by rerere (more on that later
87
- too), a notification can go out to Hipchat. The Hipchat notifier needs your token (api v2 token) and the room
88
- to which the message will be sent.
89
-
90
85
  ### Runtime options
91
86
 
92
87
  #### -v, --version
data/flash_flow.gemspec CHANGED
@@ -5,11 +5,11 @@ require 'flash_flow/version'
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "flash_flow"
7
7
  spec.version = FlashFlow::VERSION
8
- spec.authors = ["Flashfunders"]
9
- spec.email = ["engineering@flashfunders.com"]
10
- spec.summary = %q{Implementation of the flashfunders workflow}
8
+ spec.authors = ["Brad Bennett"]
9
+ spec.email = ["bradleyjaybennett@gmail.com"]
10
+ spec.summary = %q{Merge your open prs together}
11
11
  spec.description = %q{Flash flow is a command line tool for keeping your acceptance environment up to date}
12
- spec.homepage = "https://github.com/FlashFunders/flash_flow"
12
+ spec.homepage = "https://github.com/bradleyjucsc/flash_flow"
13
13
  spec.license = "MIT"
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0")
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.require_paths = ["lib"]
19
19
 
20
20
  spec.add_dependency 'octokit', "~> 4.1"
21
- spec.add_dependency 'hipchat', "~> 1.5"
21
+ spec.add_dependency 'tb-bjb', "~> 1.6"
22
22
  spec.add_dependency 'pivotal-tracker', "~> 0.5"
23
23
  spec.add_dependency 'ruby-graphviz', "> 0"
24
24
  spec.add_dependency 'percy-client'
@@ -29,6 +29,6 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency "bundler", "~> 1.6"
30
30
  spec.add_development_dependency "rake", "> 0"
31
31
  spec.add_development_dependency "minitest", "> 0"
32
- spec.add_development_dependency "byebug", "> 0"
32
+ # spec.add_development_dependency "byebug", "> 0"
33
33
  spec.add_development_dependency 'minitest-stub_any_instance', "> 0"
34
34
  end
@@ -8,9 +8,9 @@ git:
8
8
  # Which remote your branches use
9
9
  remote: origin
10
10
 
11
- # This branch is owned by flash_flow, it force pushes every time. So don't use a branch to which you make
12
- # commits. Treat this as 100% ephemeral, but if you can you should deploy it automatically to your
13
- # review/staging env when it gets pushed.
11
+ # This branch is owned by flash_flow, and will be overwritten. Don't use a branch to which you make
12
+ # commits. Treat this as 100% ephemeral, this is the branch that you should deploy automatically to
13
+ # your review/staging env.
14
14
  merge_branch: acceptance
15
15
 
16
16
  # This is your mainline production branch that is the basis for the merge branch
@@ -19,23 +19,13 @@ git:
19
19
  # An arbitrary file that flash_flow will write to in the merge branch and use to store branch information.
20
20
  # Make sure it doesn't collide with a file you actually need in your application. You don't need to look at
21
21
  # this file in general.
22
- branch_info_file: 'your/random/file'
22
+ branch_info_file: 'flash_flow.json'
23
23
 
24
24
 
25
25
 
26
26
  ### Everything below here is optional and should be deleted or remain commented out if you don't need it
27
27
 
28
28
 
29
- ## This will send merge conflict notifications to the hipchat room configured below, only for branches
30
- ## other than your own.
31
-
32
- #notifier:
33
- # class:
34
- # name: 'FlashFlow::Notifier::Hipchat'
35
- # token: <%= ENV['HIPCHAT_TOKEN'] %>
36
- # room: 'Flash Flow Notifications'
37
-
38
-
39
29
  ## If you use Pivotal Tracker, this integration can finish, deliver, un-deliver, and comment when
40
30
  ## deployed to production if you set it up.
41
31
  ## Must be used in conjuction with the "--story or --stories" options.
@@ -10,7 +10,7 @@ module FlashFlow
10
10
  attr_accessor :dir
11
11
 
12
12
  def initialize(opts={})
13
- @dir = opts[:dir] || '.'
13
+ @dir = opts[:dir] || `pwd`.strip
14
14
  @dry_run = opts[:dry_run]
15
15
  @logger = opts[:logger] || Logger.new('/dev/null')
16
16
  end
@@ -51,4 +51,4 @@ module FlashFlow
51
51
  end
52
52
  end
53
53
  end
54
- end
54
+ end
@@ -2,6 +2,7 @@ require 'logger'
2
2
  require 'singleton'
3
3
  require 'yaml'
4
4
  require 'erb'
5
+ require 'fileutils'
5
6
 
6
7
  module FlashFlow
7
8
  class Config
@@ -40,13 +41,24 @@ module FlashFlow
40
41
  instance.instance_variable_set("@#{attr_name}", config[attr_name])
41
42
  end
42
43
 
43
- instance.instance_variable_set(:@logger, Logger.new(instance.log_file))
44
+ instance.instance_variable_set(:@logger, get_logger(instance.log_file))
44
45
 
45
46
  raise IncompleteConfiguration.new("Missing attributes:\n #{missing_attrs.join("\n ")}") unless missing_attrs.empty?
46
47
 
47
48
  instance.instance_variable_set(:@configured, true)
48
49
  end
49
50
 
51
+ def self.get_logger(log_file)
52
+ if log_file.to_s.empty?
53
+ log_file = '/dev/null'
54
+ else
55
+ dir = File.dirname(log_file)
56
+ FileUtils.mkdir_p(dir)
57
+ end
58
+ Logger.new(log_file)
59
+
60
+ end
61
+
50
62
  def self.defaults
51
63
  {
52
64
  branch_info_file: 'README.rdoc',
@@ -25,7 +25,7 @@ module FlashFlow
25
25
  def initialize_collection(branch_config)
26
26
  stored_collection = Collection.from_hash(stored_branches)
27
27
 
28
- if ! branch_config.empty?
28
+ if branch_config && !branch_config.empty?
29
29
  collection = Collection.fetch(branch_config)
30
30
  # Order matters. We are marking the PRs as current, not the branches stored in the json
31
31
  collection.mark_all_as_current
@@ -0,0 +1,152 @@
1
+ require 'tinybucket'
2
+ require 'flash_flow/data/branch'
3
+
4
+ module FlashFlow
5
+ module Data
6
+ class Bitbucket
7
+
8
+ attr_accessor :repo, :unmergeable_label
9
+
10
+ def initialize(config={})
11
+ initialize_connection!(config['oauth_token'], config['oauth_secret'])
12
+ @repo_owner = config['repo_owner']
13
+ @repo = config['repo']
14
+ @master_branch = config['master_branch'] || 'master'
15
+ @unmergeable_label = config['unmergeable_label'] || 'Flash Flow -- Unmergeable'
16
+ @do_not_merge_label = config['do_not_merge_label'] || 'Flash Flow -- Do Not Merge'
17
+ # @code_reviewed_label = config['code_reviewed_label'] || 'code reviewed'
18
+ # @shippable_label = config['shippable_label'] || 'shippable'
19
+ end
20
+
21
+ def initialize_connection!(oauth_token, oauth_secret)
22
+ if oauth_token.nil? || oauth_secret.nil?
23
+ raise RuntimeError.new("Oauth token and Oauth secret must be set in your flash_flow config file.")
24
+ end
25
+ Tinybucket.configure do |config|
26
+ config.oauth_token = oauth_token
27
+ config.oauth_secret = oauth_secret
28
+ end
29
+ end
30
+
31
+ def remove_from_merge(branch)
32
+ pr = pr_for(branch)
33
+ if pr && @do_not_merge_label
34
+ add_labeling(pr, @do_not_merge_label)
35
+ end
36
+ end
37
+
38
+ def fetch
39
+ pull_requests.map do |pr|
40
+ Branch.from_hash(
41
+ 'ref' => pr.source['branch']['name'],
42
+ 'status' => status_from_labeling(pr),
43
+ 'metadata' => metadata(pr),
44
+ 'sha' => pr.source['commit']['hash']
45
+ )
46
+ end
47
+ end
48
+
49
+ def add_to_merge(branch)
50
+ pr = pr_for(branch)
51
+
52
+ pr ||= create_pr(branch.ref, branch.ref, branch.ref)
53
+ branch.add_metadata(metadata(pr))
54
+
55
+ if pr && @do_not_merge_label
56
+ remove_labeling(pr, @do_not_merge_label)
57
+ end
58
+ end
59
+
60
+ def mark_success(branch)
61
+ remove_labeling(pr_for(branch), @unmergeable_label)
62
+ end
63
+
64
+ def mark_failure(branch)
65
+ add_labeling(pr_for(branch), @unmergeable_label)
66
+ end
67
+
68
+ def code_reviewed?(branch)
69
+ is_labeled?(pr_for(branch), @code_reviewed_label)
70
+ end
71
+
72
+ def can_ship?(branch)
73
+ is_labeled?(pr_for(branch), @shippable_label)
74
+ end
75
+
76
+ def branch_link(branch)
77
+ branch.metadata['pr_url']
78
+ end
79
+
80
+ private
81
+
82
+ def status_from_labeling(pr)
83
+ case
84
+ when is_labeled?(pr, @do_not_merge_label)
85
+ 'removed'
86
+ when is_labeled?(pr, @unmergeable_label)
87
+ 'fail'
88
+ else
89
+ nil
90
+ end
91
+ end
92
+
93
+ def pr_for(branch)
94
+ pull_requests.detect { |pr| branch.ref == pr.source['branch']['name'] }
95
+ end
96
+
97
+ def create_pr(branch, title, body)
98
+ pr_resource = Tinybucket::Resource::PullRequests.new(repo_obj, [])
99
+ pr = pr_resource.create(source: { branch: { name: branch }}, title: title, description: body)
100
+ pull_requests << pr
101
+ pr
102
+ end
103
+
104
+ def pull_requests
105
+ @pull_requests ||= repo_obj.pull_requests.sort_by(&:created_on)
106
+ end
107
+
108
+ def labeling_string(label)
109
+ " --- #{label}"
110
+ end
111
+
112
+ def labeling_regex(label)
113
+ /#{Regexp.escape(labeling_string(label))}$/
114
+ end
115
+
116
+ def remove_labeling(pr, label)
117
+ if is_labeled?(pr, label)
118
+ pr.title.gsub!(labeling_regex(label), '')
119
+ pr.update
120
+ end
121
+ end
122
+
123
+ def add_labeling(pr, label)
124
+ unless is_labeled?(pr, label)
125
+ pr.title += labeling_string(label)
126
+ pr.update
127
+ end
128
+ end
129
+
130
+ def is_labeled?(pr, label)
131
+ pr.title =~ labeling_regex(label)
132
+ end
133
+
134
+ def metadata(pr)
135
+ {
136
+ 'pr_number' => pr.id,
137
+ 'pr_url' => pr.links['html']['href'],
138
+ 'user_url' => pr.author['links']['html']['href'],
139
+ 'repo_url' => repo_obj.links['html']['href']
140
+ }
141
+ end
142
+
143
+ def repo_obj
144
+ @repo_obj ||= begin
145
+ repo = Tinybucket.new.repo(@repo_owner, @repo)
146
+ repo.load
147
+ repo
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
@@ -1,5 +1,6 @@
1
1
  require 'flash_flow/data/branch'
2
2
  require 'flash_flow/data/github'
3
+ require 'flash_flow/data/bitbucket'
3
4
 
4
5
  module FlashFlow
5
6
  module Data
@@ -92,10 +92,6 @@ module FlashFlow
92
92
  pull_requests.detect { |p| branch.ref == p.head.ref }
93
93
  end
94
94
 
95
- def update_pr(pr_number)
96
- octokit.update_pull_request(repo, pr_number, {})
97
- end
98
-
99
95
  def create_pr(branch, title, body)
100
96
  pr = octokit.create_pull_request(repo, @master_branch, branch, title, body)
101
97
  pull_requests << pr
@@ -49,6 +49,10 @@ module FlashFlow
49
49
  @cmd_runner.run("git #{cmd}", opts)
50
50
  end
51
51
 
52
+ def working_dir
53
+ @cmd_runner.dir
54
+ end
55
+
52
56
  def add_and_commit(files, message, opts={})
53
57
  files = [files].flatten
54
58
  run("add #{'-f ' if opts[:add] && opts[:add][:force]}#{files.join(' ')}")
@@ -77,11 +81,12 @@ module FlashFlow
77
81
  last_stdout
78
82
  end
79
83
 
80
- def initialize_rerere
84
+ def initialize_rerere(copy_from_dir=nil)
81
85
  return unless use_rerere
82
86
 
83
87
  @cmd_runner.run('mkdir .git/rr-cache')
84
88
  @cmd_runner.run('cp -R rr-cache/* .git/rr-cache/')
89
+ @cmd_runner.run("cp -R #{File.join(copy_from_dir, '.git/rr-cache/*')} .git/rr-cache/") if copy_from_dir
85
90
  end
86
91
 
87
92
  def commit_rerere(current_rereres)
@@ -168,11 +173,12 @@ module FlashFlow
168
173
  run("branch -D #{temp_merge_branch}")
169
174
  run("checkout -b #{temp_merge_branch}")
170
175
  run("reset --hard #{remote}/#{master_branch}")
176
+ run("clean -x -f -d")
171
177
  end
172
178
  end
173
179
 
174
180
  def push(branch, force=false)
175
- run("push #{'-f' if force} #{remote} #{branch}")
181
+ run("push #{'-f' if force} #{remote} #{branch}:#{branch}")
176
182
  end
177
183
 
178
184
  def copy_temp_to_branch(branch, squash_message = nil)
@@ -210,7 +216,7 @@ module FlashFlow
210
216
  end
211
217
 
212
218
  def temp_merge_branch
213
- "flash_flow/#{merge_branch}"
219
+ "flash_flow-#{merge_branch}"
214
220
  end
215
221
 
216
222
  def get_sha(branch, opts={})
@@ -231,6 +237,15 @@ module FlashFlow
231
237
  branch_exists?(branch) && !master_branch_contains?(get_sha(branch))
232
238
  end
233
239
 
240
+ def version
241
+ run('--version')
242
+ semver_regex = Regexp.new('.*(\d+\.\d+\.\d+).*')
243
+ running_version = last_stdout.strip
244
+ if semver = semver_regex.match(running_version)
245
+ semver[1]
246
+ end
247
+ end
248
+
234
249
  private
235
250
 
236
251
  def squash_commits(branch, commit_message)
@@ -18,6 +18,7 @@ module FlashFlow
18
18
 
19
19
  def run
20
20
  check_version
21
+ check_git_version
21
22
  check_repo
22
23
  puts "Building #{@local_git.merge_branch}... Log can be found in #{FlashFlow::Config.configuration.log_file}"
23
24
  logger.info "\n\n### Beginning #{@local_git.merge_branch} merge ###\n\n"
@@ -27,12 +28,14 @@ module FlashFlow
27
28
 
28
29
  @lock.with_lock do
29
30
  @git.in_original_merge_branch do
30
- @git.initialize_rerere
31
+ @git.initialize_rerere(@local_git.working_dir)
31
32
  end
32
33
 
33
34
  @git.reset_temp_merge_branch
34
35
  @git.in_temp_merge_branch do
35
36
  merge_branches(@data.mergeable) do |branch, merger|
37
+ # Do not merge the master branch or the merge branch
38
+ next if [@git.merge_branch, @git.master_branch].include?(branch.ref)
36
39
  process_result(branch, merger)
37
40
  end
38
41
  commit_branch_info
@@ -101,7 +104,7 @@ module FlashFlow
101
104
  raise OutOfSyncWithRemote.new("Your branch is out of sync with the remote. If you want to force push, run 'flash_flow -f'") unless @local_git.last_success?
102
105
 
103
106
  if @do_not_merge
104
- @data.remove_from_merge(@local_git.remote, @local_git.working_branch)
107
+ @data.remove_from_merge(@local_git.working_branch)
105
108
  else
106
109
  @data.add_to_merge(@local_git.working_branch)
107
110
  end
@@ -47,6 +47,19 @@ module FlashFlow
47
47
  end
48
48
  end
49
49
 
50
+ def check_git_version
51
+ git_version = @local_git.version
52
+ return if git_version.nil?
53
+
54
+ running_version = git_version.split(".").map(&:to_i)
55
+ expected_version = FlashFlow::GIT_VERSION.split(".").map(&:to_i)
56
+
57
+ if running_version[0] < expected_version[0] ||
58
+ (running_version[0] == expected_version[0] && running_version[1] < expected_version[1]) # Ignore the point release number
59
+ puts "Warning: Your version of git (#{git_version}) is behind the version that is tested (#{FlashFlow::GIT_VERSION}). We recommend to upgrade to at least #{expected_version[0]}.#{expected_version[1]}.0"
60
+ end
61
+ end
62
+
50
63
  def merge_branches(branches)
51
64
  ordered_branches = MergeOrder.new(@git, branches).get_order
52
65
  ordered_branches.each_with_index do |branch, index|
@@ -15,6 +15,7 @@ module FlashFlow
15
15
 
16
16
  def send_mail
17
17
  check_version
18
+ check_git_version
18
19
  puts "Checking #{@git.release_branch} QA approval"
19
20
  logger.info "\n\n### Beginning check of #{@git.release_branch} QA ###\n\n"
20
21
 
@@ -36,6 +37,7 @@ module FlashFlow
36
37
  def run
37
38
  begin
38
39
  check_version
40
+ check_git_version
39
41
  puts "Merging #{@git.release_branch} into #{@git.master_branch}"
40
42
  logger.info "\n\n### Beginning merge of #{@git.release_branch} into #{@git.master_branch} ###\n\n"
41
43
 
@@ -21,6 +21,7 @@ module FlashFlow
21
21
  def run
22
22
  begin
23
23
  check_version
24
+ check_git_version
24
25
  check_branches
25
26
  puts "Merging these branches into #{@git.release_branch}:\n #{@release_branches.map(&:ref).join("\n ")}"
26
27
  logger.info "\n\n### Beginning #{@local_git.merge_branch} merge ###\n\n"
@@ -1,5 +1,4 @@
1
1
  require 'flash_flow/data'
2
- require 'flash_flow/notifier/hipchat'
3
2
 
4
3
  module FlashFlow
5
4
  module Notifier
@@ -1,3 +1,4 @@
1
1
  module FlashFlow
2
- VERSION = '1.5.3'
2
+ VERSION = '1.6.0'
3
+ GIT_VERSION = '2.0.0'
3
4
  end
@@ -47,8 +47,30 @@ module FlashFlow
47
47
  end
48
48
  end
49
49
 
50
- def test_check_version_equal
50
+ def test_git_version_is_nil
51
+ with_git_versions(nil, '2.0.0') do
52
+ assert_nil(@deploy.check_git_version)
53
+ end
54
+ end
55
+
56
+ def test_check_git_version_greater
57
+ with_git_versions('3.0.0', '2.0.0') do
58
+ assert_nil(@deploy.check_git_version)
59
+ end
60
+
61
+ with_git_versions('2.15.1', '2.0.0') do
62
+ assert_nil(@deploy.check_git_version)
63
+ end
64
+ end
65
+
66
+ def test_check_git_version_less_raises
67
+ with_git_versions('2.0.0', '2.15.1') do
68
+ assert_output(/Warning/) { @deploy.check_git_version }
69
+ end
51
70
 
71
+ with_git_versions('1.7.8', '2.15.1') do
72
+ assert_output(/Warning/) { @deploy.check_git_version }
73
+ end
52
74
  end
53
75
 
54
76
  def test_print_errors_with_no_errors
@@ -162,6 +184,17 @@ module FlashFlow
162
184
  FlashFlow.const_set(:VERSION, original_version)
163
185
  end
164
186
 
187
+ def with_git_versions(running, expected)
188
+ original_version = FlashFlow::GIT_VERSION
189
+ FlashFlow.send(:remove_const, :GIT_VERSION)
190
+ FlashFlow.const_set(:GIT_VERSION, expected)
191
+ local_git.expect(:version, running)
192
+ yield
193
+ local_git.verify
194
+ FlashFlow.send(:remove_const, :GIT_VERSION)
195
+ FlashFlow.const_set(:GIT_VERSION, original_version)
196
+ end
197
+
165
198
  def merger
166
199
  @merger ||= Minitest::Mock.new
167
200
  end
@@ -180,6 +213,13 @@ module FlashFlow
180
213
  @deploy.instance_variable_set('@data'.to_sym, @data)
181
214
  end
182
215
 
216
+ def local_git
217
+ return @local_git if @local_git
218
+
219
+ @local_git = Minitest::Mock.new
220
+ @deploy.instance_variable_set('@local_git'.to_sym, @local_git)
221
+ end
222
+
183
223
  def sample_branches
184
224
  @sample_branches ||= [Data::Branch.from_hash({'ref' => 'branch3', 'merge_order' => 2}),
185
225
  Data::Branch.from_hash({'ref' => 'branch1', 'merge_order' => 3}),
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flash_flow
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.3
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
- - Flashfunders
7
+ - Brad Bennett
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-06 00:00:00.000000000 Z
11
+ date: 2018-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: octokit
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '4.1'
27
27
  - !ruby/object:Gem::Dependency
28
- name: hipchat
28
+ name: tb-bjb
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.5'
33
+ version: '1.6'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.5'
40
+ version: '1.6'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: pivotal-tracker
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -164,20 +164,6 @@ dependencies:
164
164
  - - ">"
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
- - !ruby/object:Gem::Dependency
168
- name: byebug
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - ">"
172
- - !ruby/object:Gem::Version
173
- version: '0'
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - ">"
179
- - !ruby/object:Gem::Version
180
- version: '0'
181
167
  - !ruby/object:Gem::Dependency
182
168
  name: minitest-stub_any_instance
183
169
  requirement: !ruby/object:Gem::Requirement
@@ -195,7 +181,7 @@ dependencies:
195
181
  description: Flash flow is a command line tool for keeping your acceptance environment
196
182
  up to date
197
183
  email:
198
- - engineering@flashfunders.com
184
+ - bradleyjaybennett@gmail.com
199
185
  executables:
200
186
  - flash_flow
201
187
  extensions: []
@@ -217,6 +203,7 @@ files:
217
203
  - lib/flash_flow/config.rb
218
204
  - lib/flash_flow/data.rb
219
205
  - lib/flash_flow/data/base.rb
206
+ - lib/flash_flow/data/bitbucket.rb
220
207
  - lib/flash_flow/data/branch.rb
221
208
  - lib/flash_flow/data/collection.rb
222
209
  - lib/flash_flow/data/github.rb
@@ -239,7 +226,6 @@ files:
239
226
  - lib/flash_flow/merge/status.rb
240
227
  - lib/flash_flow/merge_order.rb
241
228
  - lib/flash_flow/notifier.rb
242
- - lib/flash_flow/notifier/hipchat.rb
243
229
  - lib/flash_flow/options.rb
244
230
  - lib/flash_flow/release.rb
245
231
  - lib/flash_flow/release/pdf_diff_generator.rb
@@ -278,7 +264,7 @@ files:
278
264
  - test/lib/test_resolve.rb
279
265
  - test/minitest_helper.rb
280
266
  - update_gem.sh
281
- homepage: https://github.com/FlashFunders/flash_flow
267
+ homepage: https://github.com/bradleyjucsc/flash_flow
282
268
  licenses:
283
269
  - MIT
284
270
  metadata: {}
@@ -298,10 +284,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
298
284
  version: '0'
299
285
  requirements: []
300
286
  rubyforge_project:
301
- rubygems_version: 2.6.9
287
+ rubygems_version: 2.5.2
302
288
  signing_key:
303
289
  specification_version: 4
304
- summary: Implementation of the flashfunders workflow
290
+ summary: Merge your open prs together
305
291
  test_files:
306
292
  - test/fixtures/pdf_diff/0cbafd97ee4904001e47c0d7a4a6e4b2ee7ed830458c8616466f7a631dfeb3ce.png
307
293
  - test/fixtures/pdf_diff/142ef42e828a35e3e128f47277cb73e56215f5a81c53923c657634ac574cca07.png
@@ -1,40 +0,0 @@
1
- require 'hipchat'
2
-
3
- module FlashFlow
4
- module Notifier
5
- class Hipchat
6
-
7
- def initialize(config={})
8
- @client = initialize_connection!(config['token'])
9
- @room = config['room']
10
- end
11
-
12
- def merge_conflict(branch)
13
- begin
14
- user_name = branch.metadata['user_url'].split('/').last
15
- user_url_link = %{<a href="#{branch.metadata['user_url']}">#{user_name}</a>}
16
- ref_link = %{<a href="#{branch.metadata['repo_url']}/tree/#{branch.ref}">#{branch.ref}</a>}
17
-
18
- message = %{#{user_url_link}'s branch (#{ref_link}) did not merge successfully}
19
- @client[@room].send("FlashFlow", message)
20
- rescue HipChat::UnknownResponseCode => e
21
- puts e.message
22
- end
23
- end
24
-
25
- private
26
-
27
- def initialize_connection!(token)
28
- if token.nil?
29
- raise RuntimeError.new("Hipchat token must be set in your flash flow config.")
30
- end
31
-
32
- hipchat_client.new(token, api_version: "v2")
33
- end
34
-
35
- def hipchat_client
36
- HipChat::Client
37
- end
38
- end
39
- end
40
- end