diff --git a/Gemfile b/Gemfile index 93b2ca4..2ac34ee 100644 --- a/Gemfile +++ b/Gemfile @@ -51,6 +51,9 @@ gem 'bitbucket_rest_api' gem "taskmapper", "~> 0.8.0" gem "taskmapper-unfuddle", "~> 0.7.0" +# Jira +gem 'jira-ruby', :require => 'jira' + # Notification services # --------------------------------------- # Campfire ( We can't upgrade to 1.0 because drop support of ruby 1.8 diff --git a/Gemfile.lock b/Gemfile.lock index 0e88608..8a461e6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -123,6 +123,7 @@ GEM multipart-post (~> 1.1) faraday_middleware (0.8.8) faraday (>= 0.7.4, < 0.9) + ffi (1.9.0) flowdock (0.3.1) httparty (~> 0.7) multi_json @@ -154,6 +155,10 @@ GEM inherited_resources (1.4.0) has_scope (~> 0.5.0) responders (~> 0.9) + jira-ruby (0.1.2) + activesupport + oauth + railties journey (1.0.4) jquery-rails (2.1.4) railties (>= 3.0, < 5.0) @@ -207,6 +212,7 @@ GEM nokogiri (1.5.10) nokogiri-happymapper (0.5.7) nokogiri (~> 1.5) + oauth (0.4.7) oauth2 (0.8.1) faraday (~> 0.8) httpauth (~> 0.1) @@ -413,6 +419,7 @@ DEPENDENCIES htmlentities httparty inherited_resources + jira-ruby jquery-rails (~> 2.1.4) kaminari (>= 0.14.1) launchy diff --git a/app/assets/images/jira_active.png b/app/assets/images/jira_active.png new file mode 100644 index 0000000..d71bf0f Binary files /dev/null and b/app/assets/images/jira_active.png differ diff --git a/app/assets/images/jira_create.png b/app/assets/images/jira_create.png new file mode 100644 index 0000000..6025b7a Binary files /dev/null and b/app/assets/images/jira_create.png differ diff --git a/app/assets/images/jira_goto.png b/app/assets/images/jira_goto.png new file mode 100644 index 0000000..941d94f Binary files /dev/null and b/app/assets/images/jira_goto.png differ diff --git a/app/assets/images/jira_inactive.png b/app/assets/images/jira_inactive.png new file mode 100644 index 0000000..c66d138 Binary files /dev/null and b/app/assets/images/jira_inactive.png differ diff --git a/app/models/issue_tracker.rb b/app/models/issue_tracker.rb index ee25648..689d3ab 100644 --- a/app/models/issue_tracker.rb +++ b/app/models/issue_tracker.rb @@ -17,6 +17,14 @@ class IssueTracker field :subdomain, :type => String field :milestone_id, :type => String + # Is there any better way to enhance the props? Putting them into the subclass leads to + # an error while rendering the form fields -.- + field :base_url, :type => String + field :context_path, :type => String + field :issue_type, :type => String + field :issue_component, :type => String + field :issue_priority, :type => String + validate :check_params # Subclasses are responsible for overwriting this method. diff --git a/app/models/issue_trackers/jira_tracker.rb b/app/models/issue_trackers/jira_tracker.rb new file mode 100644 index 0000000..57a4d25 --- /dev/null +++ b/app/models/issue_trackers/jira_tracker.rb @@ -0,0 +1,109 @@ +if defined? JIRA + class IssueTrackers::JiraTracker < IssueTracker + Label = 'jira' + + Fields = [ + [:base_url, { + :label => 'Jira URL without trailing slash', + :placeholder => 'https://jira.example.org/' + }], + [:context_path, { + :optional => true, + :label => 'Context Path (Just "/" if empty otherwise with leading slash)', + :placeholder => "/jira" + }], + [:username, { + :optional => true, + :label => 'HTTP Basic Auth User', + :placeholder => 'johndoe' + }], + [:password, { + :optional => true, + :label => 'HTTP Basic Auth Password', + :placeholder => 'p@assW0rd' + }], + [:project_id, { + :label => 'Project Key', + :placeholder => 'The project Key where the issue will be created' + }], + [:account, { + :optional => true, + :label => 'Assign to this user. If empty, Jira takes the project default.', + :placeholder => "username" + }], + [:issue_component, { + :label => 'Issue category', + :placeholder => 'Website - Other' + }], + [:issue_type, { + :label => 'Issue type', + :placeholder => 'Bug' + }], + [:issue_priority, { + :label => 'Priority', + :placeholder => 'Normal' + }] + ] + + def check_params + if Fields.detect { |f| self[f[0]].blank? && !f[1][:optional] } + errors.add :base, 'You must specify all non optional values!' + end + end + + + # + # @param problem Problem + def create_issue(problem, reported_by = nil) + options = { + :username => username, + :password => password, + :site => base_url, + :context_path => context_path, + :auth_type => :basic + } + client = JIRA::Client.new(options) + + issue = { + :fields => { + :project => { + :key => project_id + }, + :summary => issue_title(problem), + :description => body_template.result(binding), + :issuetype => { + :name => issue_type + }, + :priority => { + :name => issue_priority, + }, + + :components => [{:name => issue_component}] + } + } + + issue[:fields][:assignee] = {:name => account} if account + + issue_build = client.Issue.build + issue_build.save(issue) + issue_build.fetch + + problem.update_attributes( + :issue_link => "#{base_url}#{context_path}browse/#{issue_build.key}", + :issue_type => Label + ) + + # Maybe in a later version? + #remote_link = { + # :url => app_problem_url(problem.app, problem), + # :name => "Link to Errbit Issue" + #} + #remote_link_build = issue_build.remotelink.build + #remote_link_build.save(remote_link) + end + + def body_template + @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/jira_body.txt.erb")) + end + end +end \ No newline at end of file diff --git a/app/views/issue_trackers/jira_body.txt.erb b/app/views/issue_trackers/jira_body.txt.erb new file mode 100644 index 0000000..8974f93 --- /dev/null +++ b/app/views/issue_trackers/jira_body.txt.erb @@ -0,0 +1,17 @@ +<% if notice = problem.notices.first %> +h2. Summary +<% if notice.request['url'].present? %> +h3. URL + +"<%= notice.request['url'] %>":<%= notice.request['url'] %> +<% end %> +h3. Where + +<%= notice.where %> + +h3. When + +<%= notice.created_at.to_s(:micro) %> + +"More Details on Errbit":<%= app_problem_url problem.app, problem %> +<% end %> \ No newline at end of file -- libgit2 0.21.2