flash_flow 1.4.9 → 1.4.10

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: 2ff14ebe3a079bc64c495fbe66f528e08f6c9114
4
- data.tar.gz: d50b3136f470ffc95cd2120c5b3db0035a4f81cd
3
+ metadata.gz: 952e4f7a486fdb5f394ff02c131bf51fac271d54
4
+ data.tar.gz: 4c7c524879fcf1902f899609b2e5fd2c53cb208c
5
5
  SHA512:
6
- metadata.gz: b28bf44030d7ce604b797b198f0c7b1bde4636e360a69da26494360c8096635ee7184dc35e66035c632caf8468a259b9b46cc4609e1deeea4377f3e8d57417b3
7
- data.tar.gz: a6a37d3ff1fe2ec6bc41ce96ac82e48fa43c0406e3a145239853e3c5185b19f9dafa69f0f2d14961b3005e4cd0f48f00b4174ab4bcdf227edeca3b1e50da73a2
6
+ metadata.gz: 9303c67f43148c4bbaddf614a16d36bfe14f1f5ed7bad729c9f3916af849fa9a427ffc5159ba3927bdbc9d842530d310ca4e4349c5d3922f70b8a804cf4fa6d7
7
+ data.tar.gz: efa60f954abd042a8f714d4d3ee50f1cb5b3f50c401c16bcde11a62f34d9be79904567f9be9772e8c5165e067cedcd1501ea929603dc757c1bf96a1261dbaf2d
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- flash_flow (1.4.9)
4
+ flash_flow (1.4.10)
5
+ google-api-client
5
6
  hipchat (~> 1.5)
6
7
  mail
7
8
  octokit (~> 4.1)
@@ -27,6 +28,24 @@ GEM
27
28
  unf (>= 0.0.5, < 1.0.0)
28
29
  faraday (0.9.2)
29
30
  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)
46
+ multi_json (~> 1.11)
47
+ os (~> 0.9)
48
+ signet (~> 0.7)
30
49
  hipchat (1.5.3)
31
50
  httparty
32
51
  mimemagic
@@ -34,9 +53,16 @@ GEM
34
53
  domain_name (~> 0.5)
35
54
  httparty (0.14.0)
36
55
  multi_xml (>= 0.5.2)
37
- httpclient (2.8.2)
56
+ httpclient (2.8.2.2)
57
+ hurley (0.2)
58
+ jwt (1.5.4)
59
+ little-plugger (1.1.4)
60
+ logging (2.1.0)
61
+ little-plugger (~> 1.1)
62
+ multi_json (~> 1.10)
38
63
  mail (2.6.4)
39
64
  mime-types (>= 1.16, < 4)
65
+ memoist (0.14.0)
40
66
  mime-types (3.1)
41
67
  mime-types-data (~> 3.2015)
42
68
  mime-types-data (3.2016.0521)
@@ -44,6 +70,7 @@ GEM
44
70
  mini_portile2 (2.1.0)
45
71
  minitest (5.3.5)
46
72
  minitest-stub_any_instance (1.0.1)
73
+ multi_json (1.12.1)
47
74
  multi_xml (0.5.5)
48
75
  multipart-post (2.0.0)
49
76
  netrc (0.11.0)
@@ -54,6 +81,7 @@ GEM
54
81
  nokogiri (~> 1.5)
55
82
  octokit (4.3.0)
56
83
  sawyer (~> 0.7.0, >= 0.5.3)
84
+ os (0.9.6)
57
85
  pdf-core (0.6.1)
58
86
  percy-client (1.6.0)
59
87
  faraday (>= 0.9)
@@ -69,17 +97,27 @@ GEM
69
97
  pdf-core (~> 0.6.1)
70
98
  ttfunk (~> 1.4.0)
71
99
  rake (10.4.2)
100
+ representable (2.3.0)
101
+ uber (~> 0.0.7)
72
102
  rest-client (2.0.0)
73
103
  http-cookie (>= 1.0.2, < 2.0)
74
104
  mime-types (>= 1.16, < 4.0)
75
105
  netrc (~> 0.8)
106
+ retriable (2.1.0)
76
107
  ruby-graphviz (1.2.2)
77
108
  safe_yaml (1.0.4)
78
109
  sawyer (0.7.0)
79
110
  addressable (>= 2.3.5, < 2.5)
80
111
  faraday (~> 0.8, < 0.10)
112
+ signet (0.7.3)
113
+ addressable (~> 2.3)
114
+ faraday (~> 0.9)
115
+ jwt (~> 1.5)
116
+ multi_json (~> 1.10)
81
117
  slop (3.6.0)
118
+ thor (0.19.1)
82
119
  ttfunk (1.4.0)
120
+ uber (0.0.15)
83
121
  unf (0.1.4)
84
122
  unf_ext
85
123
  unf_ext (0.0.7.2)
data/bin/flash_flow CHANGED
@@ -36,6 +36,8 @@ case
36
36
  FlashFlow::Release::Base.new(FlashFlow::Config.configuration.release).gen_pdf_diffs(*options[:gen_pdf_diffs])
37
37
  when options[:merge_release]
38
38
  FlashFlow::Merge::Master.new(options).run
39
+ when options[:notify_compliance]
40
+ FlashFlow::Release::Base.new(FlashFlow::Config.configuration.release).send_compliance_email
39
41
  else
40
42
  FlashFlow::Merge::Acceptance.new(options).run
41
43
  FlashFlow::IssueTracker::Base.new(FlashFlow::Config.configuration.issue_tracker).stories_pushed
data/flash_flow.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency 'percy-client'
25
25
  spec.add_dependency 'mail'
26
26
  spec.add_dependency 'prawn'
27
+ spec.add_dependency 'google-api-client'
27
28
 
28
29
  spec.add_development_dependency "bundler", "~> 1.6"
29
30
  spec.add_development_dependency "rake", "> 0"
@@ -89,8 +89,20 @@ branch_info_file: 'your/random/file'
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'
92
+ # compliance:
93
+ # max_wait_time: minutes to wait
94
+ # delay: minutes between checks
95
+ # file_prefix: 'Release_Candidate_'
96
+ # permissions:
97
+ # group:
98
+ # reader: comma-delimited list of emails
99
+ # writer: comma-delimited list of emails
100
+ # user:
101
+ # reader: comma-delimited list of emails
102
+ # writer: comma-delimited list of emails
103
+ # notify: true
104
+ # message: 'string for the message body. %percy_url% will be replaced with the url to the percy build'
105
+
94
106
  #smtp:
95
107
  # settings:
96
108
  # domain: 'yourdomain.com'
@@ -101,8 +113,9 @@ branch_info_file: 'your/random/file'
101
113
  # authentication: 'plain'
102
114
  # enable_starttls_auto: true
103
115
  # 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'
116
+ # release_ready:
117
+ # from: 'sender@domain.com'
118
+ # to: 'receiver@domain.com'
119
+ # cc: 'cc@domain.com'
120
+ # subject: 'The engineering team has a new release candidate'
121
+ # body_file: 'path/to/email_template.erb'
@@ -0,0 +1,43 @@
1
+ require 'google/api_client/client_secrets'
2
+ require 'google/apis/drive_v3'
3
+
4
+ module FlashFlow
5
+ module Release
6
+ class GoogleDrive
7
+
8
+ attr_reader :client
9
+
10
+ DRIVE = Google::Apis::DriveV3
11
+
12
+ def initialize
13
+ scopes = [DRIVE::AUTH_DRIVE]
14
+ @client = DRIVE::DriveService.new
15
+ @client.authorization = Google::Auth.get_application_default(scopes)
16
+ end
17
+
18
+ def upload_file(local_file, config={})
19
+ metadata = DRIVE::File.new(name: File.basename(local_file), extension: 'pdf')
20
+ metadata = @client.create_file(metadata, upload_source: local_file, content_type: 'application/pdf')
21
+ set_file_permissions(metadata.id, config)
22
+ end
23
+
24
+ def find_files(query)
25
+ response = @client.list_files(q: query)
26
+ response.files
27
+ end
28
+
29
+ def set_file_permissions(file_id, config={})
30
+ @client.batch do
31
+ %w(group user).each do |type|
32
+ %w(reader writer).each do |role| # owner is currently not supported
33
+ config.dig('permissions', type, role).to_s.split(',').each do |email|
34
+ permission = DRIVE::Permission.new(role: role, type: type, email_address: email)
35
+ @client.create_permission(file_id, permission, email_message: config[:email_body], send_notification_email: config['notify'])
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -27,6 +27,7 @@ module FlashFlow
27
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(',') }
28
28
  opts.on('--gen-pdf-diffs output_file,build_id,threshold', 'Generate a pdf file with screenshot differences for the specified (latest) build. output_file is required. build_id defaults to the latest build. threshold defaults to 0') { |v| options[:gen_pdf_diffs] = v.split(',') }
29
29
  opts.on('--merge-release', 'Merge the release branch into the master branch and push') { |v| options[:merge_release] = true }
30
+ opts.on('--notify-compliance', 'Send the compliance notification email if everything is ready') { |v| options[:notify_compliance] = true }
30
31
 
31
32
  opts.on_tail('-h', '--help', 'Show this message') do
32
33
  puts opts
@@ -17,6 +17,10 @@ module FlashFlow
17
17
  @release.find_latest_by_sha(sha) if @release.respond_to?(:find_latest_by_sha)
18
18
  end
19
19
 
20
+ def send_compliance_email
21
+ @release.send_compliance_email if @release.respond_to?(:send_compliance_email)
22
+ end
23
+
20
24
  def send_release_email
21
25
  @release.send_release_email if @release.respond_to?(:send_release_email)
22
26
  end
@@ -2,6 +2,7 @@ require 'percy'
2
2
  require 'flash_flow/git'
3
3
  require 'flash_flow/mailer'
4
4
  require 'flash_flow/release/pdf_diff_generator'
5
+ require 'flash_flow/google_drive'
5
6
 
6
7
  module FlashFlow
7
8
  module Release
@@ -10,6 +11,7 @@ module FlashFlow
10
11
  def initialize(config={})
11
12
  @client = initialize_connection!(config)
12
13
  @git = ShadowGit.new(Config.configuration.git, Config.configuration.logger)
14
+ @compliance_config = config['compliance']
13
15
  end
14
16
 
15
17
  def find_latest_by_sha(sha)
@@ -18,10 +20,20 @@ module FlashFlow
18
20
  find_build_by_commit_id(response, commit['id'])
19
21
  end
20
22
 
23
+ def send_compliance_email
24
+ max_wait_time = @compliance_config['max_wait_time'] || 0
25
+ delay = @compliance_config['delay'] || 1
26
+ build = find_completed_build_by_sha(get_latest_sha, max_wait_time, delay)
27
+
28
+ unless build_approved?(build)
29
+ gen_compliance_pdf_file(build)
30
+ end
31
+ end
32
+
21
33
  def send_release_email
22
34
  build = find_latest_by_sha(get_latest_sha)
23
35
 
24
- if has_unapproved_diffs?(build)
36
+ unless build_approved?(build)
25
37
  mailer.deliver!(:compliance, { percy_build_url: build['web-url'] })
26
38
  end
27
39
  end
@@ -39,8 +51,52 @@ module FlashFlow
39
51
 
40
52
  private
41
53
 
54
+ def find_completed_build_by_sha(sha, max_wait_time=5, delay=1)
55
+ max_wait_time *= 60
56
+ delay *= 60
57
+ build = find_latest_by_sha(sha)
58
+ start_time = Time.now
59
+
60
+ until build_completed?(build) do
61
+ return nil if Time.now - start_time >= max_wait_time
62
+ putc '#'
63
+ sleep delay
64
+ build = find_latest_by_sha(sha)
65
+ end
66
+ build
67
+ end
68
+
69
+ def gen_compliance_pdf_file(build)
70
+ build_id = extract_build_id(build)
71
+ base_file_name = gen_compliance_file_name(build_id)
72
+ drive = GoogleDrive.new
73
+ existing_files = drive.find_files("name contains '#{File.basename(base_file_name)}' and mimeType = 'application/pdf'")
74
+
75
+ if existing_files.empty?
76
+ file_name = "#{base_file_name}_#{Time.now.strftime('%Y%m%dT%H%M')}.pdf"
77
+ gen_pdf_diffs(file_name, build_id)
78
+
79
+ puts "Uploading #{file_name} to Google Drive"
80
+ drive.upload_file(file_name, @compliance_config.merge({ email_body: compose_compliance_email_body(build) }))
81
+ else
82
+ puts "This build has already been processed: #{existing_files.first.name}."
83
+ end
84
+ end
85
+
86
+ def gen_compliance_file_name(build_id)
87
+ "/tmp/#{@compliance_config['file_prefix']}#{build_id}"
88
+ end
89
+
90
+ def compose_compliance_email_body(build)
91
+ @compliance_config['message'].sub('%percy_url%', build['web-url'])
92
+ end
93
+
42
94
  def get_build_id(sha=nil)
43
95
  build = find_latest_by_sha(sha || get_latest_sha)
96
+ extract_build_id(build)
97
+ end
98
+
99
+ def extract_build_id(build)
44
100
  build['web-url'].split('/').last
45
101
  end
46
102
 
@@ -75,19 +131,24 @@ module FlashFlow
75
131
 
76
132
  def builds_collection(response)
77
133
  response.fetch('data', [])
78
- .select do |h| h['type'] == 'builds' &&
134
+ .select do |h|
135
+ h['type'] == 'builds' &&
79
136
  h.dig('attributes', 'web-url') &&
80
137
  h.dig('relationships', 'commit', 'data', 'type') == 'commits'
81
- end
138
+ end
82
139
  end
83
140
 
84
141
  def commits_data(response)
85
- response.fetch('included', {'id' => nil})
142
+ response.fetch('included', { 'id' => nil })
86
143
  .select { |data| data['type'] == 'commits' }
87
144
  end
88
145
 
89
- def has_unapproved_diffs?(build)
90
- build['total-comparisons-diff'] > 0 && build['approved-at'].nil?
146
+ def build_approved?(build)
147
+ !build.nil? && !build['approved-at'].nil?
148
+ end
149
+
150
+ def build_completed?(build)
151
+ build['state'] == 'finished';
91
152
  end
92
153
 
93
154
  def get_latest_sha
@@ -1,3 +1,3 @@
1
1
  module FlashFlow
2
- VERSION = '1.4.9'
2
+ VERSION = '1.4.10'
3
3
  end
@@ -59,10 +59,10 @@ module FlashFlow
59
59
  def test_has_unapproved_diffs?
60
60
  @percy_client.stub(:get_builds, sample_response) do
61
61
  build1 = @percy_client.find_latest_by_sha('bbbbb')
62
- assert(@percy_client.send(:has_unapproved_diffs?, build1))
62
+ refute(@percy_client.send(:build_approved?, build1))
63
63
 
64
64
  build2 = @percy_client.find_latest_by_sha('aaaaa')
65
- refute(@percy_client.send(:has_unapproved_diffs?, build2))
65
+ assert(@percy_client.send(:build_approved?, build2))
66
66
  end
67
67
  end
68
68
 
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.9
4
+ version: 1.4.10
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-18 00:00:00.000000000 Z
11
+ date: 2016-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: octokit
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: google-api-client
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: bundler
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -208,6 +222,7 @@ files:
208
222
  - lib/flash_flow/data/github.rb
209
223
  - lib/flash_flow/data/store.rb
210
224
  - lib/flash_flow/git.rb
225
+ - lib/flash_flow/google_drive.rb
211
226
  - lib/flash_flow/install.rb
212
227
  - lib/flash_flow/issue_tracker.rb
213
228
  - lib/flash_flow/issue_tracker/pivotal.rb