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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4aff3163ea68205769ff9157ffcc3186797b571c
4
- data.tar.gz: d917594c16e2f836b6572922a227df7f696bbd39
3
+ metadata.gz: 4b4faf52faa0345d39f5a6b125d897a33ef97dc6
4
+ data.tar.gz: 96e3e0f1160587d5bbd972a4357f82c92807704d
5
5
  SHA512:
6
- metadata.gz: 39d51941b834bc218524412c37e7fd02309a3e947e39aad06ff5b45ff0815fa65c79bb6939accff3c98072c0c119e3e82753f195c1f9901101ae27b5694c4238
7
- data.tar.gz: 75ba31076eaa53acb0f84a81088f7dcd4e21e892e03bd9903be25ba38df81f4c87c3fd747f49bead11ce399bf6857b6643d16a14fe0f60c412b56df2917d585f
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.5)
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
- mime-types (3.1)
37
- mime-types-data (~> 3.2015)
38
- mime-types-data (3.2016.0521)
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"
@@ -85,7 +85,24 @@ branch_info_file: 'your/random/file'
85
85
 
86
86
  #release:
87
87
  # class:
88
- # name: 'FlashFlow::Release::Percy'
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
@@ -7,3 +7,4 @@ require 'flash_flow/issue_tracker'
7
7
  require 'flash_flow/resolve'
8
8
  require 'flash_flow/merge'
9
9
  require 'flash_flow/release'
10
+ require 'flash_flow/mailer'
@@ -16,7 +16,7 @@ module FlashFlow
16
16
  end
17
17
 
18
18
  ATTRIBUTES = [
19
- :git, :branch_info_file, :log_file, :notifier, :issue_tracker, :lock, :branches, :release
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
 
@@ -4,6 +4,7 @@ require 'shellwords'
4
4
  module FlashFlow
5
5
  class Git
6
6
  ATTRIBUTES = [:remote, :merge_branch, :master_branch, :release_branch, :use_rerere]
7
+
7
8
  attr_reader *ATTRIBUTES
8
9
  attr_reader :working_branch
9
10
 
@@ -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
@@ -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
@@ -15,6 +15,10 @@ module FlashFlow
15
15
  @release.find_latest_by_sha(sha) if @release.respond_to?(:find_latest_by_sha)
16
16
  end
17
17
 
18
+ def send_release_email
19
+ @release.send_release_email if @release.respond_to?(:send_release_email)
20
+ end
21
+
18
22
  end
19
23
  end
20
24
  end
@@ -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
- build = find_build_by_commit_id(response, commit['id'])
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
- { url: build['web-url'], approved: !build['approved-at'].nil? }
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
- builds = builds_collection(response)
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['data'].select do |h|
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
- end
59
+ end
59
60
  end
60
61
 
61
62
  def commits_data(response)
62
- response['included'].select { |data| data['type'] == 'commits' }
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
@@ -1,3 +1,3 @@
1
1
  module FlashFlow
2
- VERSION = "1.4.5"
2
+ VERSION = "1.4.6"
3
3
  end
@@ -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.send(:find_latest_by_sha, 'aaaaa')
15
- assert_equal(results[:url], 'https://percy.io/repo/builds/2222')
16
- assert_equal(results[:approved], true)
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": "9999"
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
@@ -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.5
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-13 00:00:00.000000000 Z
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