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 +4 -4
- data/.ruby-version +1 -1
- data/Gemfile +0 -1
- data/Gemfile.lock +88 -78
- data/README.md +0 -5
- data/flash_flow.gemspec +6 -6
- data/flash_flow.yml.erb.example +4 -14
- data/lib/flash_flow/cmd_runner.rb +2 -2
- data/lib/flash_flow/config.rb +13 -1
- data/lib/flash_flow/data/base.rb +1 -1
- data/lib/flash_flow/data/bitbucket.rb +152 -0
- data/lib/flash_flow/data/collection.rb +1 -0
- data/lib/flash_flow/data/github.rb +0 -4
- data/lib/flash_flow/git.rb +18 -3
- data/lib/flash_flow/merge/acceptance.rb +5 -2
- data/lib/flash_flow/merge/base.rb +13 -0
- data/lib/flash_flow/merge/master.rb +2 -0
- data/lib/flash_flow/merge/release.rb +1 -0
- data/lib/flash_flow/notifier.rb +0 -1
- data/lib/flash_flow/version.rb +2 -1
- data/test/lib/merge/test_acceptance.rb +41 -1
- metadata +11 -25
- data/lib/flash_flow/notifier/hipchat.rb +0 -40
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d6ebf90cccffeac908c0d843e1b41ecda291b996
|
|
4
|
+
data.tar.gz: dafdf83630955c37b97a715653cf43c2f560cd96
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4b705feb54f7c4e126129541ec072b75a75da229c74b9ca89b8da7f4a7defdb3cb9ab45acffce4905aee915e819c9bb33be0a3d48571e8ccc7a60b8aba8b6958
|
|
7
|
+
data.tar.gz: 0a3433d37f0e5158af98313741bb84e5bd3116a83c14fb6d066248dcbcf2ab594716598abab456f9e8cb3986e04aba138aaae36e288712ea461d5ff0cf4942c5
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.3.
|
|
1
|
+
2.3.4
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,135 +1,145 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
flash_flow (1.
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
27
|
-
|
|
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
|
-
|
|
34
|
+
excon (0.62.0)
|
|
35
|
+
faraday (0.15.4)
|
|
30
36
|
multipart-post (>= 1.2, < 3)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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 (
|
|
54
|
+
os (>= 0.9, < 2.0)
|
|
48
55
|
signet (~> 0.7)
|
|
49
|
-
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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.
|
|
69
|
-
|
|
70
|
-
mini_portile2 (2.
|
|
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.
|
|
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.
|
|
78
|
-
mini_portile2 (~> 2.
|
|
79
|
-
nokogiri-happymapper (0.
|
|
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.
|
|
82
|
-
sawyer (~> 0.
|
|
83
|
-
os (0.
|
|
84
|
-
pdf-core (0.
|
|
85
|
-
percy-client (
|
|
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.
|
|
95
|
-
pdf-core (~> 0.
|
|
96
|
-
ttfunk (~> 1.
|
|
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 (
|
|
99
|
-
|
|
100
|
-
|
|
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 (
|
|
105
|
-
ruby-graphviz (1.2.
|
|
106
|
+
retriable (3.1.2)
|
|
107
|
+
ruby-graphviz (1.2.4)
|
|
106
108
|
safe_yaml (1.0.4)
|
|
107
|
-
sawyer (0.
|
|
108
|
-
addressable (>= 2.3.5, < 2.
|
|
109
|
-
faraday (~> 0.8, < 0
|
|
110
|
-
signet (0.
|
|
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 (
|
|
115
|
+
jwt (>= 1.5, < 3.0)
|
|
114
116
|
multi_json (~> 1.10)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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.
|
|
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.
|
|
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 = ["
|
|
9
|
-
spec.email = ["
|
|
10
|
-
spec.summary = %q{
|
|
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/
|
|
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 '
|
|
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
|
data/flash_flow.yml.erb.example
CHANGED
|
@@ -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,
|
|
12
|
-
# commits. Treat this as 100% ephemeral,
|
|
13
|
-
# review/staging env
|
|
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: '
|
|
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
|
data/lib/flash_flow/config.rb
CHANGED
|
@@ -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,
|
|
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',
|
data/lib/flash_flow/data/base.rb
CHANGED
|
@@ -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 !
|
|
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
|
|
@@ -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
|
data/lib/flash_flow/git.rb
CHANGED
|
@@ -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
|
|
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.
|
|
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"
|
data/lib/flash_flow/notifier.rb
CHANGED
data/lib/flash_flow/version.rb
CHANGED
|
@@ -47,8 +47,30 @@ module FlashFlow
|
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
def
|
|
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.
|
|
4
|
+
version: 1.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- Brad Bennett
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
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:
|
|
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.
|
|
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.
|
|
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
|
-
-
|
|
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/
|
|
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.
|
|
287
|
+
rubygems_version: 2.5.2
|
|
302
288
|
signing_key:
|
|
303
289
|
specification_version: 4
|
|
304
|
-
summary:
|
|
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
|