flash_flow 1.4.5 → 1.4.6
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/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
|