flash_flow 1.4.5 → 1.4.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -4
- data/bin/flash_flow +2 -0
- data/flash_flow.gemspec +1 -0
- data/flash_flow.yml.erb.example +18 -1
- data/lib/flash_flow.rb +1 -0
- data/lib/flash_flow/config.rb +3 -2
- data/lib/flash_flow/git.rb +1 -0
- data/lib/flash_flow/mailer.rb +45 -0
- data/lib/flash_flow/options.rb +1 -1
- data/lib/flash_flow/release.rb +4 -0
- data/lib/flash_flow/release/percy_client.rb +30 -16
- data/lib/flash_flow/version.rb +1 -1
- data/test/lib/release/test_percy_client.rb +60 -4
- data/test/lib/test_config.rb +4 -3
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b4faf52faa0345d39f5a6b125d897a33ef97dc6
|
4
|
+
data.tar.gz: 96e3e0f1160587d5bbd972a4357f82c92807704d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d513f6f38ac8bd6e8e44e2e380975f7fafd9c1f28c60999b1d91d33312daff171fd97e855a3d9fdcfa5f1190dad7ae4f3caab9b5336d7531d1dd96b13a0b372d
|
7
|
+
data.tar.gz: 5767d8b4b74060742e2a50b50aaa7b782c7858fec8badbfc4d6c2e05402052b3f285c0ca13029a4f6920b28a82b1ac194571e93f7d4c924f0bd67bdaab52bbb4
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
flash_flow (1.4.
|
4
|
+
flash_flow (1.4.6)
|
5
5
|
hipchat (~> 1.5)
|
6
|
+
mail
|
6
7
|
octokit (~> 4.1)
|
7
8
|
percy-client
|
8
9
|
pivotal-tracker (~> 0.5)
|
@@ -33,9 +34,9 @@ GEM
|
|
33
34
|
httparty (0.14.0)
|
34
35
|
multi_xml (>= 0.5.2)
|
35
36
|
httpclient (2.8.0)
|
36
|
-
|
37
|
-
mime-types
|
38
|
-
mime-types
|
37
|
+
mail (2.6.3)
|
38
|
+
mime-types (>= 1.16, < 3)
|
39
|
+
mime-types (2.99.2)
|
39
40
|
mimemagic (0.3.1)
|
40
41
|
mini_portile2 (2.1.0)
|
41
42
|
minitest (5.3.5)
|
data/bin/flash_flow
CHANGED
@@ -20,6 +20,8 @@ case
|
|
20
20
|
FlashFlow::IssueTracker::Base.new(FlashFlow::Config.configuration.issue_tracker).stories_delivered
|
21
21
|
when options[:release_notes]
|
22
22
|
FlashFlow::IssueTracker::Base.new(FlashFlow::Config.configuration.issue_tracker).release_notes(options[:release_notes])
|
23
|
+
when options[:release_email]
|
24
|
+
FlashFlow::Release::Base.new(FlashFlow::Config.configuration.release).send_release_email
|
23
25
|
when options[:resolve]
|
24
26
|
FlashFlow::Resolve.new(FlashFlow::Config.configuration.git, FlashFlow::Config.configuration.branch_info_file, logger: FlashFlow::Config.configuration.logger).start
|
25
27
|
when options[:resolve_manual]
|
data/flash_flow.gemspec
CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_dependency 'pivotal-tracker', "~> 0.5"
|
23
23
|
spec.add_dependency 'ruby-graphviz', "> 0"
|
24
24
|
spec.add_dependency 'percy-client'
|
25
|
+
spec.add_dependency 'mail'
|
25
26
|
|
26
27
|
spec.add_development_dependency "bundler", "~> 1.6"
|
27
28
|
spec.add_development_dependency "rake", "> 0"
|
data/flash_flow.yml.erb.example
CHANGED
@@ -85,7 +85,24 @@ branch_info_file: 'your/random/file'
|
|
85
85
|
|
86
86
|
#release:
|
87
87
|
# class:
|
88
|
-
# name: 'FlashFlow::Release::
|
88
|
+
# name: 'FlashFlow::Release::PercyClient'
|
89
89
|
# token: <%= ENV['PERCY_TOKEN'] %>
|
90
90
|
# repo: # Your github repo. For example, the flash_flow repo is 'flashfunders/flash_flow'
|
91
91
|
# api_url: 'https://percy.io/api/v1/'
|
92
|
+
# email: 'foo@bar.com'
|
93
|
+
# cc_email: 'bar@foo.com'
|
94
|
+
#smtp:
|
95
|
+
# settings:
|
96
|
+
# domain: 'yourdomain.com'
|
97
|
+
# address: <%= ENV['SMTP_ADDRESS'] %>
|
98
|
+
# user_name: <%= ENV['SMTP_USERNAME'] %>
|
99
|
+
# password: <%= ENV['SMTP_PASSWORD'] %>
|
100
|
+
# port: 587
|
101
|
+
# authentication: 'plain'
|
102
|
+
# enable_starttls_auto: true
|
103
|
+
# emails:
|
104
|
+
# from: 'sender@domain.com'
|
105
|
+
# to: 'receiver@domain.com'
|
106
|
+
# cc: 'cc@domain.com'
|
107
|
+
# subject: 'The engineering team has a new release candidate'
|
108
|
+
# body_file: 'path/to/email_template.erb'
|
data/lib/flash_flow.rb
CHANGED
data/lib/flash_flow/config.rb
CHANGED
@@ -16,7 +16,7 @@ module FlashFlow
|
|
16
16
|
end
|
17
17
|
|
18
18
|
ATTRIBUTES = [
|
19
|
-
|
19
|
+
:git, :branch_info_file, :log_file, :notifier, :issue_tracker, :lock, :branches, :release, :smtp
|
20
20
|
]
|
21
21
|
|
22
22
|
attr_reader *ATTRIBUTES
|
@@ -55,7 +55,8 @@ module FlashFlow
|
|
55
55
|
issue_tracker: nil,
|
56
56
|
lock: nil,
|
57
57
|
branches: nil,
|
58
|
-
release: nil
|
58
|
+
release: nil,
|
59
|
+
smtp: nil
|
59
60
|
}
|
60
61
|
end
|
61
62
|
|
data/lib/flash_flow/git.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'mail'
|
2
|
+
|
3
|
+
module FlashFlow
|
4
|
+
module Mailer
|
5
|
+
class Base
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
unless config&.fetch('settings', false)
|
9
|
+
raise RuntimeError.new("smtp settings must be set in your flash flow config.")
|
10
|
+
end
|
11
|
+
|
12
|
+
configure!(config['settings'])
|
13
|
+
end
|
14
|
+
|
15
|
+
def deliver!(data={})
|
16
|
+
delivery_info = Config.configuration.smtp["emails"]
|
17
|
+
|
18
|
+
if delivery_info
|
19
|
+
delivery_info["body_html"] = body_html(data, delivery_info["body_file"])
|
20
|
+
|
21
|
+
Mail.deliver do
|
22
|
+
from delivery_info["from"]
|
23
|
+
to delivery_info["to"]
|
24
|
+
cc delivery_info["cc"]
|
25
|
+
subject delivery_info["subject"]
|
26
|
+
body delivery_info["body_html"]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def configure!(config)
|
34
|
+
Mail.defaults { delivery_method :smtp, config.symbolize_keys }
|
35
|
+
end
|
36
|
+
|
37
|
+
def body_html(data, template)
|
38
|
+
@data = data
|
39
|
+
erb_template = ERB.new File.read(template)
|
40
|
+
erb_template.result(binding)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/flash_flow/options.rb
CHANGED
@@ -13,6 +13,7 @@ module FlashFlow
|
|
13
13
|
opts.on('--prod-deploy', 'Run IssueTracker#deploy_production and exit') { |v| options[:prod_deploy] = true }
|
14
14
|
opts.on('--review-deploy', 'Run IssueTracker#deploy_review and exit') { |v| options[:review_deploy] = true }
|
15
15
|
opts.on('--release-notes hours', 'Run IssueTracker#release_notes and exit') { |v| options[:release_notes] = v }
|
16
|
+
opts.on('--release-email', 'Send an email with a latest build info and exit') { |v| options[:release_email] = v }
|
16
17
|
opts.on('-n', '--no-merge', 'Run flash flow, but do not merge this branch') { |v| options[:do_not_merge] = true }
|
17
18
|
opts.on('--rerere-forget', 'Delete the saved patch for this branch and let the merge fail if there is a conflict') { |v| options[:rerere_forget] = true }
|
18
19
|
opts.on('--story id1', 'story id for this branch') { |v| options[:stories] = [v] }
|
@@ -24,7 +25,6 @@ module FlashFlow
|
|
24
25
|
opts.on('--merge-status', 'Show status of all branches and their stories and exit') { |v| options[:merge_status] = true }
|
25
26
|
opts.on('--merge-status-html', 'Show status of all branches and their stories in html format and exit') { |v| options[:merge_status_html] = true }
|
26
27
|
opts.on('--make-release branch1,branch2', 'Comma-delimited list of branches to merge to the release branch. Run "--merge-release ready" to merge all ready to ship branches') { |v| options[:release_branches] = v.split(',') }
|
27
|
-
opts.on('--merge-release', 'Merge the release branch into the master branch and push') { |v| options[:merge_release] = v.split(',') }
|
28
28
|
|
29
29
|
opts.on_tail("-h", "--help", "Show this message") do
|
30
30
|
puts opts
|
data/lib/flash_flow/release.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'percy'
|
2
|
+
require 'flash_flow/git'
|
3
|
+
require 'flash_flow/mailer'
|
2
4
|
|
3
5
|
module FlashFlow
|
4
6
|
module Release
|
@@ -6,14 +8,21 @@ module FlashFlow
|
|
6
8
|
|
7
9
|
def initialize(config={})
|
8
10
|
@client = initialize_connection!(config['token'])
|
11
|
+
@git = ShadowGit.new(Config.configuration.git, Config.configuration.logger)
|
9
12
|
end
|
10
13
|
|
11
14
|
def find_latest_by_sha(sha)
|
12
15
|
response = get_builds
|
13
16
|
commit = find_commit_by_sha(response, sha)
|
14
|
-
|
17
|
+
find_build_by_commit_id(response, commit['id'])
|
18
|
+
end
|
19
|
+
|
20
|
+
def send_release_email
|
21
|
+
build = find_latest_by_sha(get_latest_sha)
|
15
22
|
|
16
|
-
|
23
|
+
if has_unapproved_diffs?(build)
|
24
|
+
mailer.deliver!(percy_build_url: build['web-url'])
|
25
|
+
end
|
17
26
|
end
|
18
27
|
|
19
28
|
private
|
@@ -24,10 +33,6 @@ module FlashFlow
|
|
24
33
|
end
|
25
34
|
|
26
35
|
Percy.client.config.access_token = token
|
27
|
-
percy_client
|
28
|
-
end
|
29
|
-
|
30
|
-
def percy_client
|
31
36
|
Percy.client
|
32
37
|
end
|
33
38
|
|
@@ -40,26 +45,35 @@ module FlashFlow
|
|
40
45
|
end
|
41
46
|
|
42
47
|
def find_build_by_commit_id(response, commit_id)
|
43
|
-
|
44
|
-
return if builds.nil?
|
45
|
-
|
46
|
-
latest_build = builds
|
48
|
+
builds_collection(response)
|
47
49
|
.select { |b| b.dig('relationships', 'commit', 'data', 'id') == commit_id }
|
48
50
|
.sort_by { |b| DateTime.parse(b.dig('attributes', 'created-at')) }.last
|
49
|
-
|
50
|
-
latest_build['attributes']
|
51
|
+
&.fetch('attributes', {}) || {}
|
51
52
|
end
|
52
53
|
|
53
54
|
def builds_collection(response)
|
54
|
-
response
|
55
|
-
h['type'] == 'builds' &&
|
55
|
+
response.fetch('data', [])
|
56
|
+
.select do |h| h['type'] == 'builds' &&
|
56
57
|
h.dig('attributes', 'web-url') &&
|
57
58
|
h.dig('relationships', 'commit', 'data', 'type') == 'commits'
|
58
|
-
|
59
|
+
end
|
59
60
|
end
|
60
61
|
|
61
62
|
def commits_data(response)
|
62
|
-
response
|
63
|
+
response.fetch('included', {'id' => nil})
|
64
|
+
.select { |data| data['type'] == 'commits' }
|
65
|
+
end
|
66
|
+
|
67
|
+
def has_unapproved_diffs?(build)
|
68
|
+
build['total-comparisons-diff'] > 0 && build['approved-at'].nil?
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_latest_sha
|
72
|
+
@git.get_sha(@git.release_branch)
|
73
|
+
end
|
74
|
+
|
75
|
+
def mailer
|
76
|
+
@mailer ||= FlashFlow::Mailer::Base.new(Config.configuration.smtp)
|
63
77
|
end
|
64
78
|
|
65
79
|
end
|
data/lib/flash_flow/version.rb
CHANGED
@@ -6,15 +6,41 @@ module FlashFlow
|
|
6
6
|
class TestPercyClient < Minitest::Test
|
7
7
|
|
8
8
|
def setup
|
9
|
+
configuration = {}
|
10
|
+
.merge(git_config)
|
11
|
+
.merge(smtp_config)
|
12
|
+
reset_config!
|
13
|
+
config!(configuration)
|
14
|
+
|
9
15
|
@percy_client = Release::PercyClient.new({'token' => ''})
|
10
16
|
end
|
11
17
|
|
12
18
|
def test_find_latest_by_sha
|
13
19
|
@percy_client.stub(:get_builds, sample_response) do
|
14
|
-
results = @percy_client.
|
15
|
-
|
16
|
-
|
20
|
+
results = @percy_client.find_latest_by_sha('aaaaa')
|
21
|
+
assert(results.has_key?('web-url'))
|
22
|
+
assert(results.has_key?('approved-at'))
|
23
|
+
assert(results.has_key?('total-comparisons-diff'))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_send_release_email
|
28
|
+
@git = Minitest::Mock.new
|
29
|
+
.expect(:release_branch, 'release')
|
30
|
+
.expect(:get_sha, 'bbbbb', ['release'])
|
31
|
+
|
32
|
+
@mailer = Minitest::Mock.new
|
33
|
+
@mailer.expect(:deliver!, true, [{percy_build_url: 'https://percy.io/repo/builds/1111'}])
|
34
|
+
|
35
|
+
@percy_client.instance_variable_set('@git'.to_sym, @git)
|
36
|
+
@percy_client.instance_variable_set('@mailer'.to_sym, @mailer)
|
37
|
+
|
38
|
+
@percy_client.stub(:get_builds, sample_response) do
|
39
|
+
@percy_client.send_release_email
|
17
40
|
end
|
41
|
+
|
42
|
+
@git.verify
|
43
|
+
@mailer.verify
|
18
44
|
end
|
19
45
|
|
20
46
|
def test_find_commit_by_sha
|
@@ -30,6 +56,16 @@ module FlashFlow
|
|
30
56
|
assert(!build['approved-at'].nil?)
|
31
57
|
end
|
32
58
|
|
59
|
+
def test_has_unapproved_diffs?
|
60
|
+
@percy_client.stub(:get_builds, sample_response) do
|
61
|
+
build1 = @percy_client.find_latest_by_sha('bbbbb')
|
62
|
+
assert(@percy_client.send(:has_unapproved_diffs?, build1))
|
63
|
+
|
64
|
+
build2 = @percy_client.find_latest_by_sha('aaaaa')
|
65
|
+
refute(@percy_client.send(:has_unapproved_diffs?, build2))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
33
69
|
private
|
34
70
|
|
35
71
|
def sample_response
|
@@ -39,6 +75,7 @@ module FlashFlow
|
|
39
75
|
"type": "builds",
|
40
76
|
"attributes": {
|
41
77
|
"web-url": "https://percy.io/repo/builds/1111",
|
78
|
+
"total-comparisons-diff": 1,
|
42
79
|
"approved-at": null,
|
43
80
|
"created-at": "2016-08-01T00:00:00.000Z"
|
44
81
|
},
|
@@ -46,7 +83,7 @@ module FlashFlow
|
|
46
83
|
"commit": {
|
47
84
|
"data": {
|
48
85
|
"type": "commits",
|
49
|
-
"id": "
|
86
|
+
"id": "8888"
|
50
87
|
}
|
51
88
|
}
|
52
89
|
}
|
@@ -55,6 +92,7 @@ module FlashFlow
|
|
55
92
|
"type": "builds",
|
56
93
|
"attributes": {
|
57
94
|
"web-url": "https://percy.io/repo/builds/2222",
|
95
|
+
"total-comparisons-diff": 0,
|
58
96
|
"approved-at": "2016-08-01T22:41:58.000Z",
|
59
97
|
"created-at": "2016-08-01T11:11:11.111Z"
|
60
98
|
},
|
@@ -87,6 +125,24 @@ module FlashFlow
|
|
87
125
|
}')
|
88
126
|
end
|
89
127
|
|
128
|
+
def git_config
|
129
|
+
{
|
130
|
+
git: {
|
131
|
+
'merge_branch' => 'test_acceptance',
|
132
|
+
'merge_remote' => 'test_remote',
|
133
|
+
'master_branch' => 'test_master',
|
134
|
+
'remotes' => ['fake_origin'],
|
135
|
+
'use_rerere' => true
|
136
|
+
}
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
def smtp_config
|
141
|
+
{
|
142
|
+
smtp: {}
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
90
146
|
end
|
91
147
|
end
|
92
148
|
end
|
data/test/lib/test_config.rb
CHANGED
@@ -30,7 +30,8 @@ module FlashFlow
|
|
30
30
|
'class' => {
|
31
31
|
'name' => 'BranchClass'
|
32
32
|
}
|
33
|
-
}
|
33
|
+
},
|
34
|
+
'smtp' => {}
|
34
35
|
}
|
35
36
|
|
36
37
|
reset_config!
|
@@ -72,9 +73,9 @@ module FlashFlow
|
|
72
73
|
assert_nil(config.lock)
|
73
74
|
end
|
74
75
|
end
|
75
|
-
|
76
|
+
|
76
77
|
private
|
77
|
-
|
78
|
+
|
78
79
|
def config
|
79
80
|
Config.configuration
|
80
81
|
end
|
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.
|
4
|
+
version: 1.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Flashfunders
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: octokit
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: mail
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: bundler
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -185,6 +199,7 @@ files:
|
|
185
199
|
- lib/flash_flow/issue_tracker/pivotal.rb
|
186
200
|
- lib/flash_flow/lock.rb
|
187
201
|
- lib/flash_flow/lock/github.rb
|
202
|
+
- lib/flash_flow/mailer.rb
|
188
203
|
- lib/flash_flow/merge.rb
|
189
204
|
- lib/flash_flow/merge/acceptance.rb
|
190
205
|
- lib/flash_flow/merge/base.rb
|