Commit 85515aae09ce10cb32ad8e442096c554ecd6b438
Exists in
master
and in
1 other branch
Merge pull request #516 from xenji-feature/jira-issue-tracker
Conflicts: Gemfile.lock
Showing
9 changed files
with
143 additions
and
0 deletions
Show diff stats
Gemfile
@@ -50,6 +50,9 @@ gem 'bitbucket_rest_api', :require => false | @@ -50,6 +50,9 @@ gem 'bitbucket_rest_api', :require => false | ||
50 | gem "taskmapper", "~> 0.8.0" | 50 | gem "taskmapper", "~> 0.8.0" |
51 | gem "taskmapper-unfuddle", "~> 0.7.0" | 51 | gem "taskmapper-unfuddle", "~> 0.7.0" |
52 | 52 | ||
53 | +# Jira | ||
54 | +gem 'jira-ruby', :require => 'jira' | ||
55 | + | ||
53 | # Notification services | 56 | # Notification services |
54 | # --------------------------------------- | 57 | # --------------------------------------- |
55 | # Campfire ( We can't upgrade to 1.0 because drop support of ruby 1.8 | 58 | # Campfire ( We can't upgrade to 1.0 because drop support of ruby 1.8 |
Gemfile.lock
@@ -151,6 +151,10 @@ GEM | @@ -151,6 +151,10 @@ GEM | ||
151 | multi_xml (>= 0.5.2) | 151 | multi_xml (>= 0.5.2) |
152 | httpauth (0.2.0) | 152 | httpauth (0.2.0) |
153 | i18n (0.6.1) | 153 | i18n (0.6.1) |
154 | + jira-ruby (0.1.2) | ||
155 | + activesupport | ||
156 | + oauth | ||
157 | + railties | ||
154 | journey (1.0.4) | 158 | journey (1.0.4) |
155 | jquery-rails (2.1.4) | 159 | jquery-rails (2.1.4) |
156 | railties (>= 3.0, < 5.0) | 160 | railties (>= 3.0, < 5.0) |
@@ -204,6 +208,7 @@ GEM | @@ -204,6 +208,7 @@ GEM | ||
204 | nokogiri (1.5.10) | 208 | nokogiri (1.5.10) |
205 | nokogiri-happymapper (0.5.7) | 209 | nokogiri-happymapper (0.5.7) |
206 | nokogiri (~> 1.5) | 210 | nokogiri (~> 1.5) |
211 | + oauth (0.4.7) | ||
207 | oauth2 (0.8.1) | 212 | oauth2 (0.8.1) |
208 | faraday (~> 0.8) | 213 | faraday (~> 0.8) |
209 | httpauth (~> 0.1) | 214 | httpauth (~> 0.1) |
@@ -407,6 +412,7 @@ DEPENDENCIES | @@ -407,6 +412,7 @@ DEPENDENCIES | ||
407 | hoptoad_notifier (~> 2.4) | 412 | hoptoad_notifier (~> 2.4) |
408 | htmlentities | 413 | htmlentities |
409 | httparty | 414 | httparty |
415 | + jira-ruby | ||
410 | jquery-rails (~> 2.1.4) | 416 | jquery-rails (~> 2.1.4) |
411 | kaminari (>= 0.14.1) | 417 | kaminari (>= 0.14.1) |
412 | launchy | 418 | launchy |
1.97 KB
1.97 KB
1.97 KB
1.91 KB
app/models/issue_tracker.rb
@@ -17,6 +17,14 @@ class IssueTracker | @@ -17,6 +17,14 @@ class IssueTracker | ||
17 | field :subdomain, :type => String | 17 | field :subdomain, :type => String |
18 | field :milestone_id, :type => String | 18 | field :milestone_id, :type => String |
19 | 19 | ||
20 | + # Is there any better way to enhance the props? Putting them into the subclass leads to | ||
21 | + # an error while rendering the form fields -.- | ||
22 | + field :base_url, :type => String | ||
23 | + field :context_path, :type => String | ||
24 | + field :issue_type, :type => String | ||
25 | + field :issue_component, :type => String | ||
26 | + field :issue_priority, :type => String | ||
27 | + | ||
20 | validate :check_params | 28 | validate :check_params |
21 | 29 | ||
22 | # Subclasses are responsible for overwriting this method. | 30 | # Subclasses are responsible for overwriting this method. |
@@ -0,0 +1,109 @@ | @@ -0,0 +1,109 @@ | ||
1 | +if defined? JIRA | ||
2 | + class IssueTrackers::JiraTracker < IssueTracker | ||
3 | + Label = 'jira' | ||
4 | + | ||
5 | + Fields = [ | ||
6 | + [:base_url, { | ||
7 | + :label => 'Jira URL without trailing slash', | ||
8 | + :placeholder => 'https://jira.example.org/' | ||
9 | + }], | ||
10 | + [:context_path, { | ||
11 | + :optional => true, | ||
12 | + :label => 'Context Path (Just "/" if empty otherwise with leading slash)', | ||
13 | + :placeholder => "/jira" | ||
14 | + }], | ||
15 | + [:username, { | ||
16 | + :optional => true, | ||
17 | + :label => 'HTTP Basic Auth User', | ||
18 | + :placeholder => 'johndoe' | ||
19 | + }], | ||
20 | + [:password, { | ||
21 | + :optional => true, | ||
22 | + :label => 'HTTP Basic Auth Password', | ||
23 | + :placeholder => 'p@assW0rd' | ||
24 | + }], | ||
25 | + [:project_id, { | ||
26 | + :label => 'Project Key', | ||
27 | + :placeholder => 'The project Key where the issue will be created' | ||
28 | + }], | ||
29 | + [:account, { | ||
30 | + :optional => true, | ||
31 | + :label => 'Assign to this user. If empty, Jira takes the project default.', | ||
32 | + :placeholder => "username" | ||
33 | + }], | ||
34 | + [:issue_component, { | ||
35 | + :label => 'Issue category', | ||
36 | + :placeholder => 'Website - Other' | ||
37 | + }], | ||
38 | + [:issue_type, { | ||
39 | + :label => 'Issue type', | ||
40 | + :placeholder => 'Bug' | ||
41 | + }], | ||
42 | + [:issue_priority, { | ||
43 | + :label => 'Priority', | ||
44 | + :placeholder => 'Normal' | ||
45 | + }] | ||
46 | + ] | ||
47 | + | ||
48 | + def check_params | ||
49 | + if Fields.detect { |f| self[f[0]].blank? && !f[1][:optional] } | ||
50 | + errors.add :base, 'You must specify all non optional values!' | ||
51 | + end | ||
52 | + end | ||
53 | + | ||
54 | + | ||
55 | + # | ||
56 | + # @param problem Problem | ||
57 | + def create_issue(problem, reported_by = nil) | ||
58 | + options = { | ||
59 | + :username => username, | ||
60 | + :password => password, | ||
61 | + :site => base_url, | ||
62 | + :context_path => context_path, | ||
63 | + :auth_type => :basic | ||
64 | + } | ||
65 | + client = JIRA::Client.new(options) | ||
66 | + | ||
67 | + issue = { | ||
68 | + :fields => { | ||
69 | + :project => { | ||
70 | + :key => project_id | ||
71 | + }, | ||
72 | + :summary => issue_title(problem), | ||
73 | + :description => body_template.result(binding), | ||
74 | + :issuetype => { | ||
75 | + :name => issue_type | ||
76 | + }, | ||
77 | + :priority => { | ||
78 | + :name => issue_priority, | ||
79 | + }, | ||
80 | + | ||
81 | + :components => [{:name => issue_component}] | ||
82 | + } | ||
83 | + } | ||
84 | + | ||
85 | + issue[:fields][:assignee] = {:name => account} if account | ||
86 | + | ||
87 | + issue_build = client.Issue.build | ||
88 | + issue_build.save(issue) | ||
89 | + issue_build.fetch | ||
90 | + | ||
91 | + problem.update_attributes( | ||
92 | + :issue_link => "#{base_url}#{context_path}browse/#{issue_build.key}", | ||
93 | + :issue_type => Label | ||
94 | + ) | ||
95 | + | ||
96 | + # Maybe in a later version? | ||
97 | + #remote_link = { | ||
98 | + # :url => app_problem_url(problem.app, problem), | ||
99 | + # :name => "Link to Errbit Issue" | ||
100 | + #} | ||
101 | + #remote_link_build = issue_build.remotelink.build | ||
102 | + #remote_link_build.save(remote_link) | ||
103 | + end | ||
104 | + | ||
105 | + def body_template | ||
106 | + @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/jira_body.txt.erb")) | ||
107 | + end | ||
108 | + end | ||
109 | +end | ||
0 | \ No newline at end of file | 110 | \ No newline at end of file |
@@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
1 | +<% if notice = problem.notices.first %> | ||
2 | +h2. Summary | ||
3 | +<% if notice.request['url'].present? %> | ||
4 | +h3. URL | ||
5 | + | ||
6 | +"<%= notice.request['url'] %>":<%= notice.request['url'] %> | ||
7 | +<% end %> | ||
8 | +h3. Where | ||
9 | + | ||
10 | +<%= notice.where %> | ||
11 | + | ||
12 | +h3. When | ||
13 | + | ||
14 | +<%= notice.created_at.to_s(:micro) %> | ||
15 | + | ||
16 | +"More Details on Errbit":<%= app_problem_url problem.app, problem %> | ||
17 | +<% end %> | ||
0 | \ No newline at end of file | 18 | \ No newline at end of file |