Commit 2d86e4fe54e6377e42f71782352c180178f77a7b
1 parent
bf7175e0
Exists in
master
and in
1 other branch
Added jira as new issue tracker
Showing
9 changed files
with
144 additions
and
0 deletions
Show diff stats
Gemfile
... | ... | @@ -51,6 +51,9 @@ gem 'bitbucket_rest_api' |
51 | 51 | gem "taskmapper", "~> 0.8.0" |
52 | 52 | gem "taskmapper-unfuddle", "~> 0.7.0" |
53 | 53 | |
54 | +# Jira | |
55 | +gem 'jira-ruby', :require => 'jira' | |
56 | + | |
54 | 57 | # Notification services |
55 | 58 | # --------------------------------------- |
56 | 59 | # Campfire ( We can't upgrade to 1.0 because drop support of ruby 1.8 | ... | ... |
Gemfile.lock
... | ... | @@ -123,6 +123,7 @@ GEM |
123 | 123 | multipart-post (~> 1.1) |
124 | 124 | faraday_middleware (0.8.8) |
125 | 125 | faraday (>= 0.7.4, < 0.9) |
126 | + ffi (1.9.0) | |
126 | 127 | flowdock (0.3.1) |
127 | 128 | httparty (~> 0.7) |
128 | 129 | multi_json |
... | ... | @@ -154,6 +155,10 @@ GEM |
154 | 155 | inherited_resources (1.4.0) |
155 | 156 | has_scope (~> 0.5.0) |
156 | 157 | responders (~> 0.9) |
158 | + jira-ruby (0.1.2) | |
159 | + activesupport | |
160 | + oauth | |
161 | + railties | |
157 | 162 | journey (1.0.4) |
158 | 163 | jquery-rails (2.1.4) |
159 | 164 | railties (>= 3.0, < 5.0) |
... | ... | @@ -207,6 +212,7 @@ GEM |
207 | 212 | nokogiri (1.5.10) |
208 | 213 | nokogiri-happymapper (0.5.7) |
209 | 214 | nokogiri (~> 1.5) |
215 | + oauth (0.4.7) | |
210 | 216 | oauth2 (0.8.1) |
211 | 217 | faraday (~> 0.8) |
212 | 218 | httpauth (~> 0.1) |
... | ... | @@ -413,6 +419,7 @@ DEPENDENCIES |
413 | 419 | htmlentities |
414 | 420 | httparty |
415 | 421 | inherited_resources |
422 | + jira-ruby | |
416 | 423 | jquery-rails (~> 2.1.4) |
417 | 424 | kaminari (>= 0.14.1) |
418 | 425 | 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 | 17 | field :subdomain, :type => String |
18 | 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 | 28 | validate :check_params |
21 | 29 | |
22 | 30 | # Subclasses are responsible for overwriting this method. | ... | ... |
... | ... | @@ -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 | 110 | \ No newline at end of file | ... | ... |
... | ... | @@ -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 | 18 | \ No newline at end of file | ... | ... |