caperoma 0.1.0 → 4.0.1

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.
Files changed (85) hide show
  1. checksums.yaml +5 -5
  2. data/.ruby-version +1 -0
  3. data/Capefile +48 -0
  4. data/Capefile.template +48 -0
  5. data/Capefile.test +20 -0
  6. data/Gemfile +25 -10
  7. data/Gemfile.lock +196 -77
  8. data/HELP +321 -0
  9. data/README.md +528 -0
  10. data/Rakefile +73 -18
  11. data/VERSION +1 -1
  12. data/bin/caperoma +47 -11
  13. data/caperoma.gemspec +144 -45
  14. data/config/crontab +10 -0
  15. data/config/schedule.rb +21 -0
  16. data/lib/caperoma.rb +409 -9
  17. data/lib/caperoma/models/account.rb +47 -0
  18. data/lib/caperoma/models/application_record.rb +5 -0
  19. data/lib/caperoma/models/branch.rb +6 -0
  20. data/lib/caperoma/models/project.rb +14 -0
  21. data/lib/caperoma/models/property.rb +5 -0
  22. data/lib/caperoma/models/report.rb +177 -0
  23. data/lib/caperoma/models/report_recipient.rb +6 -0
  24. data/lib/caperoma/models/reports/daily_report.rb +23 -0
  25. data/lib/caperoma/models/reports/retrospective_report.rb +19 -0
  26. data/lib/caperoma/models/reports/three_day_report.rb +19 -0
  27. data/lib/caperoma/models/task.rb +368 -0
  28. data/lib/caperoma/models/tasks/bug.rb +36 -0
  29. data/lib/caperoma/models/tasks/chore.rb +40 -0
  30. data/lib/caperoma/models/tasks/feature.rb +27 -0
  31. data/lib/caperoma/models/tasks/fix.rb +56 -0
  32. data/lib/caperoma/models/tasks/meeting.rb +40 -0
  33. data/lib/caperoma/models/tasks/modules/git.rb +65 -0
  34. data/lib/caperoma/models/tasks/task_with_commit.rb +40 -0
  35. data/lib/caperoma/models/tasks/task_with_separate_branch.rb +42 -0
  36. data/lib/caperoma/services/airbrake_email_processor.rb +47 -0
  37. data/lib/caperoma/services/pivotal_fetcher.rb +108 -0
  38. data/lib/caperoma/version.rb +9 -0
  39. data/spec/caperoma_spec.rb +3 -21
  40. data/spec/factories/accounts.rb +10 -0
  41. data/spec/factories/branches.rb +9 -0
  42. data/spec/factories/projects.rb +8 -0
  43. data/spec/factories/report_recipients.rb +7 -0
  44. data/spec/factories/reports.rb +16 -0
  45. data/spec/factories/tasks.rb +37 -0
  46. data/spec/features/bug_spec.rb +60 -0
  47. data/spec/features/chore_spec.rb +60 -0
  48. data/spec/features/command_unknown_spec.rb +14 -0
  49. data/spec/features/config_spec.rb +161 -0
  50. data/spec/features/feature_spec.rb +60 -0
  51. data/spec/features/finish_spec.rb +18 -0
  52. data/spec/features/fix_spec.rb +60 -0
  53. data/spec/features/meeting_spec.rb +22 -0
  54. data/spec/features/projects_spec.rb +17 -0
  55. data/spec/features/report_recipientss_spec.rb +117 -0
  56. data/spec/features/reports_spec.rb +65 -0
  57. data/spec/features/status_spec.rb +33 -0
  58. data/spec/features/version_spec.rb +11 -0
  59. data/spec/models/account_spec.rb +51 -0
  60. data/spec/models/branch_spec.rb +8 -0
  61. data/spec/models/bug_spec.rb +33 -0
  62. data/spec/models/chore_spec.rb +33 -0
  63. data/spec/models/daily_report_spec.rb +38 -0
  64. data/spec/models/feature_spec.rb +33 -0
  65. data/spec/models/fix_spec.rb +55 -0
  66. data/spec/models/meeting_spec.rb +33 -0
  67. data/spec/models/project_spec.rb +11 -0
  68. data/spec/models/report_recipient_spec.rb +22 -0
  69. data/spec/models/report_spec.rb +16 -0
  70. data/spec/models/retrospective_report_spec.rb +38 -0
  71. data/spec/models/task_spec.rb +613 -0
  72. data/spec/models/task_with_commit_spec.rb +105 -0
  73. data/spec/models/task_with_separate_branch_spec.rb +97 -0
  74. data/spec/models/three_day_report_spec.rb +49 -0
  75. data/spec/spec_helper.rb +26 -16
  76. data/spec/support/capefile_generator.rb +36 -0
  77. data/spec/support/database_cleaner.rb +21 -0
  78. data/spec/support/stubs.rb +178 -9
  79. metadata +283 -42
  80. data/.document +0 -5
  81. data/README.rdoc +0 -26
  82. data/lib/caperoma/credentials.rb +0 -13
  83. data/lib/caperoma/jira_client.rb +0 -57
  84. data/spec/caperoma/credentials_spec.rb +0 -25
  85. data/spec/caperoma/jira_spec.rb +0 -35
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationRecord < ActiveRecord::Base
4
+ self.abstract_class = true
5
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Branch < ActiveRecord::Base
4
+ belongs_to :project
5
+ has_many :tasks
6
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Project < ApplicationRecord
4
+ has_many :branches
5
+ has_many :chores
6
+ has_many :bugs
7
+ has_many :features
8
+ has_many :meetings
9
+ has_many :fixes
10
+
11
+ def folder_path
12
+ %(#{self[:folder_path]})
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Property < ApplicationRecord
4
+ validates :name, :value, presence: true
5
+ end
@@ -0,0 +1,177 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Report < ApplicationRecord
4
+ include ActionView::Helpers::TextHelper
5
+ has_many :tasks
6
+
7
+ after_initialize :set_variables
8
+
9
+ after_create :assign_unreported_tasks
10
+ after_create :send_email, if: :not_test?
11
+ after_create :update_content
12
+
13
+ def self.schedule
14
+ # may screw up existing cron tasks
15
+ puts 'Turning on auto reports'
16
+ root = File.dirname __dir__
17
+ crontab_file = File.join root, 'config', 'crontab'
18
+ `crontab #{crontab_file}`
19
+ # > whenever --update-crontab caperoma
20
+ puts 'Auto reports turned on'
21
+ end
22
+
23
+ def self.unschedule
24
+ puts 'Turning off auto reports'
25
+ puts 'pending'
26
+ puts 'Auto reports turned off'
27
+ end
28
+
29
+ private
30
+
31
+ def set_variables
32
+ @smtp = Net::SMTP.new 'smtp.gmail.com', 587
33
+ @smtp.enable_starttls
34
+ @account = Account.gmail
35
+ end
36
+
37
+ # most of it is related to email formatting
38
+
39
+ def assign_unreported_tasks
40
+ unreported_tasks.update_all(report_sti_key => id)
41
+ end
42
+
43
+ def send_email
44
+ @smtp.start('gmail.com', @account.email, @account.password, :login, &send_email_method)
45
+ end
46
+
47
+ def send_email_method
48
+ proc { @smtp.send_message(report_msg, @account.email, to_addresses) }
49
+ end
50
+
51
+ def unreported_tasks
52
+ Task.finished.where(report_sti_key => nil)
53
+ end
54
+
55
+ def report_sti_key
56
+ self.class.to_s.foreign_key
57
+ end
58
+
59
+ def update_content
60
+ update content: report_msg
61
+ end
62
+
63
+ def reported_tasks
64
+ tasks.finished.order(finished_at: :desc)
65
+ end
66
+
67
+ def total_time_spent
68
+ "#{hours_spent}h #{remaining_minutes_spent}m"
69
+ end
70
+
71
+ def hours_spent
72
+ (total_time_spent_in_minutes / 60).to_i
73
+ end
74
+
75
+ def remaining_minutes_spent
76
+ (total_time_spent_in_minutes - hours_spent * 60).to_i
77
+ end
78
+
79
+ def total_time_spent_in_minutes
80
+ reported_tasks.all.collect(&:time_spent_in_minutes).sum
81
+ end
82
+
83
+ def not_test?
84
+ ENV['CAPEROMA_INTEGRATION_TEST'].blank? && ENV['CAPEROMA_TEST'].blank?
85
+ end
86
+
87
+ def to_addresses
88
+ ReportRecipient.all.collect(&:email)
89
+ end
90
+
91
+ def report_msg
92
+ report_msg_content.join("\n")
93
+ end
94
+
95
+ def report_msg_content
96
+ ["subject: #{report_subject}", 'Content-Type: text/html; charset=UTF-8', report_body]
97
+ end
98
+
99
+ def formatted_day(day)
100
+ day.strftime('%b %-d')
101
+ end
102
+
103
+ def formatted_start_day
104
+ formatted_day(start_day)
105
+ end
106
+
107
+ def formatted_end_day
108
+ formatted_day(end_day)
109
+ end
110
+
111
+ def timeframe
112
+ [formatted_start_day, formatted_end_day].join(' - ')
113
+ end
114
+
115
+ def report_subject
116
+ [subject_name, subject_timeframe].join(' ')
117
+ end
118
+
119
+ def subject_timeframe
120
+ "(#{timeframe})"
121
+ end
122
+
123
+ def report_body
124
+ [
125
+ "\n",
126
+ "<h2>Done during #{timeframe}:</h2>",
127
+ "<br />",
128
+ "<table style=\"width: 100%;text-align: left;\">",
129
+ "<thead>",
130
+ "<tr><th>Jira</th><th>Pivotal</th><th>Title</th><th>Time spent</th></tr>",
131
+ "</thead>",
132
+ "<tbody>",
133
+ reported_tasks_rows,
134
+ "</tbody>",
135
+ "</table>",
136
+ "<br />",
137
+ "<strong>Total time spent during #{timeframe}:</strong> #{total_time_spent}."
138
+ ].flatten.join("\n")
139
+ end
140
+
141
+ def reported_tasks_rows
142
+ reported_tasks.collect { |task| table_row(task) }.join("\n")
143
+ end
144
+
145
+ def table_row(task)
146
+ '<tr>' + task_row_data(task).collect{|task| '<td>' + task + '</td>' }.join("\n") + '</tr>'
147
+ end
148
+
149
+ def task_row_data(task)
150
+ [
151
+ jira_url_or_blank(task),
152
+ pivotal_url_or_blank(task),
153
+ formatted_title(task),
154
+ task.time_spent
155
+ ]
156
+ end
157
+
158
+ def formatted_title(task)
159
+ truncate(task.title, length: 90)
160
+ end
161
+
162
+ def jira_url_or_blank(task)
163
+ task.jira_key.present? ? jira_formatted_url(task) : ''
164
+ end
165
+
166
+ def jira_formatted_url(task)
167
+ "<a href=\"#{task.jira_live_url}\">#{task.jira_key}</a>"
168
+ end
169
+
170
+ def pivotal_url_or_blank(task)
171
+ task.pivotal_id.present? ? pivotal_formatted_url(task) : ''
172
+ end
173
+
174
+ def pivotal_formatted_url(task)
175
+ "<a href=\"#{task.pivotal_url}\">#{task.pivotal_id}</a>"
176
+ end
177
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ReportRecipient < ApplicationRecord
4
+ validates :email, presence: true, uniqueness: true
5
+ validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, on: :create # TODO: just email validator dude
6
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DailyReport < Report
4
+ has_many :tasks
5
+
6
+ private
7
+
8
+ def subject_name
9
+ 'Daily Report'
10
+ end
11
+
12
+ def body_heading
13
+ 'Today'
14
+ end
15
+
16
+ def timeframe
17
+ formatted_day(start_day)
18
+ end
19
+
20
+ def start_day
21
+ Date.today
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RetrospectiveReport < Report
4
+ has_many :tasks
5
+
6
+ private
7
+
8
+ def subject_name
9
+ 'Weekly Report'
10
+ end
11
+
12
+ def start_day
13
+ Date.today.beginning_of_week
14
+ end
15
+
16
+ def end_day
17
+ Date.today
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThreeDayReport < Report
4
+ has_many :tasks
5
+
6
+ private
7
+
8
+ def subject_name
9
+ 'Three Day Report'
10
+ end
11
+
12
+ def start_day
13
+ Date.today - 2.days
14
+ end
15
+
16
+ def end_day
17
+ Date.today
18
+ end
19
+ end
@@ -0,0 +1,368 @@
1
+ # frozen_string_literal: true
2
+ class Task < ActiveRecord::Base
3
+ include Git
4
+
5
+ belongs_to :project
6
+ belongs_to :daily_report
7
+ belongs_to :three_day_report
8
+ belongs_to :retrospective_report
9
+
10
+ validates :title, presence: true
11
+ validates :pivotal_id, length: { minimum: 6 }, allow_blank: true, numericality: { only_integer: true }
12
+
13
+ before_create :generate_uuid
14
+ before_create :set_start_time
15
+
16
+ after_create :create_issue_on_jira, if: :create_on_jira?
17
+ after_create :start_issue_on_jira, if: :start_on_jira?
18
+ after_create :create_issue_on_pivotal, if: :create_on_pivotal?
19
+ after_create :start_issue_on_pivotal, if: :start_on_pivotal?
20
+ after_save :output_jira_key, if: :output_jira_key?
21
+
22
+ scope :unfinished, -> { where(finished_at: nil) }
23
+ scope :finished, -> { where.not(finished_at: nil) }
24
+
25
+ def self.finish_started(comment)
26
+ puts 'Finishing current task'
27
+ unfinished.each { |task| task.finish(comment) }
28
+ puts 'Current task finished'
29
+ end
30
+
31
+ def self.pause_started(comment)
32
+ puts 'Pausing current task'
33
+ unfinished.each { |task| task.pause(comment) }
34
+ puts 'Current task paused'
35
+ end
36
+
37
+ def self.abort_started(comment)
38
+ puts 'Aborting current task'
39
+ unfinished.each { |task| task.abort(comment) }
40
+ puts 'Current task aborted'
41
+ end
42
+
43
+ def self.abort_started_without_time(comment)
44
+ puts 'Aborting current task without putting time into Jira'
45
+ unfinished.each { |task| task.abort_without_time(comment) }
46
+ puts 'Current task aborted without putting time into Jira'
47
+ end
48
+
49
+ def self.status
50
+ if unfinished.length == 0
51
+ puts "You are not working on anything now."
52
+ else
53
+ unfinished.each do |task|
54
+ puts "You are working on: "
55
+ puts "Title: #{task.title}"
56
+ puts "Type: #{task.type}"
57
+ puts "Jira ID: #{task.jira_key}." if task.jira_key.present?
58
+ puts "Pivotal ID: #{task.pivotal_id} (#{task.pivotal_url})" if task.pivotal_id.present?
59
+ puts "Time spent at the moment: #{task.time_spent_so_far}"
60
+ puts "Pull request will be sent to this branch: #{task.parent_branch}" if task.parent_branch.present?
61
+ puts "Project location: #{task.project.folder_path}"
62
+ end
63
+ end
64
+ end
65
+
66
+ attr_writer :additional_time
67
+
68
+ def finish(comment)
69
+ # full pull request
70
+ update_attribute(:finished_at, Time.now)
71
+ close_issue_on_jira
72
+ log_work_to_jira(comment)
73
+ finish_on_pivotal if pivotal_id.present?
74
+ puts time_spent
75
+ end
76
+
77
+ def pause(comment = 'Done')
78
+ # finish with commit & push but without pull request
79
+ update_attribute(:finished_at, Time.now)
80
+ close_issue_on_jira
81
+ log_work_to_jira(comment)
82
+ finish_on_pivotal if pivotal_id.present?
83
+ puts time_spent
84
+ end
85
+
86
+ def abort(comment)
87
+ # finish without commit or push
88
+ update_attribute(:finished_at, Time.now)
89
+ close_issue_on_jira
90
+ log_work_to_jira(comment)
91
+ finish_on_pivotal if pivotal_id.present?
92
+ puts time_spent
93
+ end
94
+
95
+ def abort_without_time(comment)
96
+ # finish without commit or push
97
+ update_attribute(:finished_at, Time.now)
98
+ close_issue_on_jira
99
+ # the task closes on Jira, but is still running in Pivotal
100
+ puts time_spent
101
+ end
102
+
103
+ def time_spent_so_far
104
+ result = TimeDifference.between(started_at, Time.now).in_minutes
105
+
106
+ hours = (result / 60).to_i
107
+ minutes = (result - hours * 60).to_i
108
+
109
+ "#{hours}h #{minutes}m"
110
+ end
111
+
112
+ def time_spent
113
+ result = TimeDifference.between(started_at, finished_at).in_minutes
114
+
115
+ hours = (result / 60).to_i
116
+ minutes = (result - hours * 60).to_i
117
+
118
+ "#{hours}h #{minutes}m"
119
+ end
120
+
121
+ def pivotal_url
122
+ "https://www.pivotaltracker.com/story/show/#{pivotal_id}" if pivotal_id.present?
123
+ end
124
+
125
+ def jira_live_url
126
+ "#{project.jira_url}browse/#{jira_key}" if jira_key.present?
127
+ end
128
+
129
+ def time_spent_in_minutes
130
+ TimeDifference.between(started_at, finished_at).in_minutes # TODO: test
131
+ end
132
+
133
+ private
134
+
135
+ def story_type
136
+ 'chore' # default is chore, it's never used directly
137
+ end
138
+
139
+ def create_on_jira?
140
+ Account.jira.present? && ENV['CAPEROMA_INTEGRATION_TEST'].blank?
141
+ end
142
+
143
+ def start_on_jira?
144
+ jira_key.present? && Account.jira.present? && ENV['CAPEROMA_INTEGRATION_TEST'].blank?
145
+ end
146
+
147
+ def create_on_pivotal?
148
+ pivotal_id.blank? && this_is_a_type_a_user_wants_to_create? && Account.pivotal.present? && ENV['CAPEROMA_INTEGRATION_TEST'].blank?
149
+ end
150
+
151
+ def start_on_pivotal?
152
+ pivotal_id.present? && Account.pivotal.present? && ENV['CAPEROMA_INTEGRATION_TEST'].blank?
153
+ end
154
+
155
+ def this_is_a_type_a_user_wants_to_create?
156
+ false
157
+ end
158
+
159
+ def generate_uuid
160
+ self.uuid = SecureRandom.uuid
161
+ end
162
+
163
+ def set_start_time
164
+ time = Time.now
165
+ time -= @additional_time.to_i.minutes if @additional_time.present?
166
+ self.started_at = time
167
+ end
168
+
169
+ def output_jira_key
170
+ puts jira_key
171
+ end
172
+
173
+ def output_jira_key?
174
+ jira_key.present? && ENV['CAPEROMA_INTEGRATION_TEST'].blank?
175
+ end
176
+
177
+ def start_issue_on_pivotal_data
178
+ Jbuilder.encode do |j|
179
+ j.current_state 'started'
180
+ end
181
+ end
182
+
183
+ def start_issue_on_pivotal
184
+ if not_test?
185
+ conn = Faraday.new(url: 'https://www.pivotaltracker.com/') do |c|
186
+ c.adapter Faraday.default_adapter
187
+ end
188
+
189
+ response = conn.put do |request|
190
+ request.url "services/v5/stories/#{pivotal_id}"
191
+ request.body = start_issue_on_pivotal_data
192
+ request.headers['User-Agent'] = 'Caperoma'
193
+ request.headers['Content-Type'] = 'application/json'
194
+ request.headers['X-TrackerToken'] = Account.pivotal.password
195
+ end
196
+ end
197
+ end
198
+
199
+ def finish_on_pivotal_data
200
+ Jbuilder.encode do |j|
201
+ j.current_state 'finished'
202
+ end
203
+ end
204
+
205
+ def finish_on_pivotal
206
+ if not_test?
207
+ conn = Faraday.new(url: 'https://www.pivotaltracker.com/') do |c|
208
+ c.adapter Faraday.default_adapter
209
+ end
210
+
211
+ response = conn.put do |request|
212
+ request.url "services/v5/stories/#{pivotal_id}"
213
+ request.body = finish_on_pivotal_data
214
+ request.headers['User-Agent'] = 'Caperoma'
215
+ request.headers['Content-Type'] = 'application/json'
216
+ request.headers['X-TrackerToken'] = Account.pivotal.password
217
+ end
218
+ end
219
+ end
220
+
221
+ def start_issue_on_jira_data
222
+ Jbuilder.encode do |j|
223
+ j.transition { j.id project.jira_transition_id_in_progress }
224
+ end
225
+ end
226
+
227
+ def start_issue_on_jira
228
+ if not_test?
229
+ conn = Faraday.new(url: project.jira_url) do |c|
230
+ c.basic_auth(Account.jira.email, Account.jira.password)
231
+ c.adapter Faraday.default_adapter
232
+ end
233
+
234
+ conn.post do |request|
235
+ request.url "rest/api/3/issue/#{jira_key}/transitions"
236
+ request.body = start_issue_on_jira_data
237
+ request.headers['User-Agent'] = 'Caperoma'
238
+ request.headers['Content-Type'] = 'application/json'
239
+ end
240
+ end
241
+ end
242
+
243
+ def close_issue_on_jira_data
244
+ Jbuilder.encode do |j|
245
+ j.transition { j.id project.jira_transition_id_done }
246
+ end
247
+ end
248
+
249
+ def close_issue_on_jira
250
+ if not_test?
251
+ conn = Faraday.new(url: project.jira_url) do |c|
252
+ c.basic_auth(Account.jira.email, Account.jira.password)
253
+ c.adapter Faraday.default_adapter
254
+ end
255
+
256
+ response = conn.post do |request|
257
+ request.url "rest/api/3/issue/#{jira_key}/transitions"
258
+ request.body = close_issue_on_jira_data
259
+ request.headers['User-Agent'] = 'Caperoma'
260
+ request.headers['Content-Type'] = 'application/json'
261
+ end
262
+ end
263
+ end
264
+
265
+ def log_work_to_jira_data(comment = 'Done')
266
+ Jbuilder.encode do |j|
267
+ j.comment comment
268
+ j.started current_time
269
+ j.timeSpent time_spent
270
+ end
271
+ end
272
+
273
+ def log_work_to_jira(comment = 'Done')
274
+ if not_test?
275
+ conn = Faraday.new(url: project.jira_url) do |c|
276
+ c.basic_auth(Account.jira.email, Account.jira.password)
277
+ c.adapter Faraday.default_adapter
278
+ end
279
+
280
+ result = conn.post do |request|
281
+ request.url "rest/api/3/issue/#{jira_key}/worklog"
282
+ request.body = log_work_to_jira_data(comment)
283
+ request.headers['User-Agent'] = 'Caperoma'
284
+ request.headers['Content-Type'] = 'application/json'
285
+ end
286
+ end
287
+ end
288
+
289
+ def current_time
290
+ Time.now.in_time_zone('UTC').strftime('%Y-%m-%dT%H:%M:00.000+0000')
291
+ end
292
+
293
+ def issue_type
294
+ project.feature_jira_task_id
295
+ end
296
+
297
+ def create_issue_on_pivotal_data
298
+ Jbuilder.encode do |j|
299
+ j.current_state 'unstarted'
300
+ j.estimate 1
301
+ j.name title.to_s
302
+ j.story_type story_type
303
+ end
304
+ end
305
+
306
+ def create_issue_on_pivotal
307
+ if not_test?
308
+ conn = Faraday.new(url: 'https://www.pivotaltracker.com/') do |c|
309
+ c.adapter Faraday.default_adapter
310
+ end
311
+
312
+ response = conn.post do |request|
313
+ request.url "services/v5/projects/#{project.pivotal_tracker_project_id}/stories"
314
+ request.body = create_issue_on_pivotal_data
315
+ request.headers['User-Agent'] = 'Caperoma'
316
+ request.headers['Content-Type'] = 'application/json'
317
+ request.headers['X-TrackerToken'] = Account.pivotal.password
318
+ end
319
+
320
+ result = JSON.parse response.body
321
+
322
+ update_attributes(
323
+ pivotal_id: result['id']
324
+ )
325
+ end
326
+ end
327
+
328
+ def create_issue_on_jira_data
329
+ Jbuilder.encode do |j|
330
+ j.fields do
331
+ j.project { j.id project.jira_project_id.to_s }
332
+ j.issuetype { j.id issue_type }
333
+ j.summary title.to_s
334
+ j.assignee do
335
+ j.name Account.jira.username
336
+ end
337
+ end
338
+ end
339
+ end
340
+
341
+ def create_issue_on_jira
342
+ if not_test?
343
+ conn = Faraday.new(url: project.jira_url) do |c|
344
+ c.basic_auth(Account.jira.email, Account.jira.password)
345
+ c.adapter Faraday.default_adapter
346
+ end
347
+
348
+ response = conn.post do |request|
349
+ request.url 'rest/api/3/issue.json'
350
+ request.body = create_issue_on_jira_data
351
+ request.headers['User-Agent'] = 'Caperoma'
352
+ request.headers['Content-Type'] = 'application/json'
353
+ end
354
+
355
+ result = JSON.parse response.body
356
+
357
+ update_attributes(
358
+ jira_id: result['id'],
359
+ jira_key: result['key'],
360
+ jira_url: result['self']
361
+ )
362
+ end
363
+ end
364
+
365
+ def not_test?
366
+ ENV['CAPEROMA_INTEGRATION_TEST'].blank?
367
+ end
368
+ end