Commit 85515aae09ce10cb32ad8e442096c554ecd6b438

Authored by Cyril Mougel
2 parents d7d17c12 2d86e4fe
Exists in master and in 1 other branch production

Merge pull request #516 from xenji-feature/jira-issue-tracker

Conflicts:
	Gemfile.lock
Gemfile
... ... @@ -50,6 +50,9 @@ gem 'bitbucket_rest_api', :require => false
50 50 gem "taskmapper", "~> 0.8.0"
51 51 gem "taskmapper-unfuddle", "~> 0.7.0"
52 52  
  53 +# Jira
  54 +gem 'jira-ruby', :require => 'jira'
  55 +
53 56 # Notification services
54 57 # ---------------------------------------
55 58 # Campfire ( We can't upgrade to 1.0 because drop support of ruby 1.8
... ...
Gemfile.lock
... ... @@ -151,6 +151,10 @@ GEM
151 151 multi_xml (>= 0.5.2)
152 152 httpauth (0.2.0)
153 153 i18n (0.6.1)
  154 + jira-ruby (0.1.2)
  155 + activesupport
  156 + oauth
  157 + railties
154 158 journey (1.0.4)
155 159 jquery-rails (2.1.4)
156 160 railties (>= 3.0, < 5.0)
... ... @@ -204,6 +208,7 @@ GEM
204 208 nokogiri (1.5.10)
205 209 nokogiri-happymapper (0.5.7)
206 210 nokogiri (~> 1.5)
  211 + oauth (0.4.7)
207 212 oauth2 (0.8.1)
208 213 faraday (~> 0.8)
209 214 httpauth (~> 0.1)
... ... @@ -407,6 +412,7 @@ DEPENDENCIES
407 412 hoptoad_notifier (~> 2.4)
408 413 htmlentities
409 414 httparty
  415 + jira-ruby
410 416 jquery-rails (~> 2.1.4)
411 417 kaminari (>= 0.14.1)
412 418 launchy
... ...
app/assets/images/jira_active.png 0 → 100644

1.97 KB

app/assets/images/jira_create.png 0 → 100644

1.97 KB

app/assets/images/jira_goto.png 0 → 100644

1.97 KB

app/assets/images/jira_inactive.png 0 → 100644

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.
... ...
app/models/issue_trackers/jira_tracker.rb 0 → 100644
... ... @@ -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
... ...
app/views/issue_trackers/jira_body.txt.erb 0 → 100644
... ... @@ -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
... ...