Commit 3456dc3d4270bc8e06f497a929c1037d51708f0c

Authored by Vasiliy Ermolovich
2 parents 4644d7b3 1c9d5f42
Exists in master and in 1 other branch production

Merge pull request #263 from shukydvir/adding_support_for_bitbucket_issues

Adding support for bitbucket issues
Gemfile
... ... @@ -38,6 +38,9 @@ gem 'ruby-fogbugz', :require => 'fogbugz'
38 38 # Github Issues
39 39 gem 'octokit', '~> 1.0.0'
40 40  
  41 +# Bitbucket Issues
  42 +gem 'bitbucket_rest_api'
  43 +
41 44 # Notification services
42 45 # ---------------------------------------
43 46 # Campfire
... ...
Gemfile.lock
... ... @@ -36,6 +36,13 @@ GEM
36 36 addressable (2.3.2)
37 37 arel (3.0.2)
38 38 bcrypt-ruby (3.0.1)
  39 + bitbucket_rest_api (0.1.1)
  40 + faraday (~> 0.8.1)
  41 + faraday_middleware (~> 0.8.1)
  42 + hashie (~> 1.2.0)
  43 + multi_json (~> 1.3)
  44 + nokogiri (~> 1.5.2)
  45 + simple_oauth
39 46 bson (1.6.2)
40 47 bson_ext (1.6.2)
41 48 bson (~> 1.6.2)
... ... @@ -268,6 +275,7 @@ GEM
268 275 libwebsocket (~> 0.1.3)
269 276 multi_json (~> 1.0)
270 277 rubyzip
  278 + simple_oauth (0.1.9)
271 279 slop (2.4.4)
272 280 sprockets (2.1.3)
273 281 hike (~> 1.2)
... ... @@ -312,6 +320,7 @@ PLATFORMS
312 320 DEPENDENCIES
313 321 SystemTimer
314 322 actionmailer_inline_css (~> 1.3.0)
  323 + bitbucket_rest_api
315 324 bson (= 1.6.2)
316 325 bson_ext (= 1.6.2)
317 326 campy
... ...
README.md
... ... @@ -362,6 +362,12 @@ card_type = Defect, status = Open, priority = Essential
362 362 * For 'Account/Repository', the account will either be a username or organization. i.e. **errbit/errbit**
363 363 * You will also need to provide your username and password for your GitHub account.
364 364 * (We'd really appreciate it if you wanted to help us implement OAuth instead!)
  365 +
  366 +**Bitbucket Issues Integration**
  367 +
  368 +* For 'BITBUCKET REPO' field, the account will either be a username or organization. i.e. **errbit/errbit**
  369 +* You will also need to provide your username and password for your Bitbucket account.
  370 +
365 371  
366 372  
367 373 What if Errbit has an error?
... ...
app/assets/images/bitbucket_create.png 0 → 100644

2.54 KB

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

3.61 KB

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

1.95 KB

app/models/issue_trackers/bitbucket_issues_tracker.rb 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +class IssueTrackers::BitbucketIssuesTracker < IssueTracker
  2 + Label = "bitbucket"
  3 + Note = 'Please configure your Bitbucket repository in the <strong>BITBUCKET REPO</strong> field above.'
  4 + Fields = [
  5 + [:api_token, {
  6 + :placeholder => "Your username on Bitbucket account",
  7 + :label => "Username"
  8 + }],
  9 + [:project_id, {
  10 + :placeholder => "Password for your Bitbucket account",
  11 + :label => "Password"
  12 + }]
  13 + ]
  14 +
  15 + def check_params
  16 + if Fields.detect {|f| self[f[0]].blank? }
  17 + errors.add :base, 'You must specify your Bitbucket username and password'
  18 + end
  19 + end
  20 +
  21 + def repo_name
  22 + app.bitbucket_repo
  23 + end
  24 +
  25 + def create_issue(problem, reported_by = nil)
  26 + bitbucket = BitBucket.new :basic_auth => "#{api_token}:#{project_id}"
  27 +
  28 + begin
  29 + issue = bitbucket.issues.create api_token, repo_name.split('/')[1], :title => issue_title(problem), :content => body_template.result(binding), :priority => 'critical'
  30 + problem.update_attributes(
  31 + :issue_link => "https://bitbucket.org/#{repo_name}/issue/#{issue.local_id}/",
  32 + :issue_type => Label
  33 + )
  34 + rescue BitBucket::Error::Unauthorized
  35 + raise IssueTrackers::AuthenticationError, "Could not authenticate with BitBucket. Please check your username and password."
  36 + end
  37 + end
  38 +
  39 + def body_template
  40 + @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/bitbucket_issues_body.txt.erb"))
  41 + end
  42 +
  43 + def url
  44 + "https://www.bitbucket.org/#{repo_name}/issues"
  45 + end
  46 +end
  47 +
... ...
app/views/issue_trackers/bitbucket_issues_body.txt.erb 0 → 100644
... ... @@ -0,0 +1,58 @@
  1 +[[<%= app_problem_url problem.app, problem %>| [See this exception on Errbit]]]
  2 +
  3 +----
  4 +
  5 +<% if notice = problem.notices.first %>
  6 + <%= notice.message %>
  7 +
  8 +----
  9 +
  10 + == Summary ==
  11 + <% if notice.request['url'].present? %>
  12 + === URL ===
  13 + [[<%= notice.request['url'] %>]]
  14 + <% end %>
  15 +
  16 +----
  17 +
  18 + === Where ===
  19 + <%= notice.where %>
  20 +
  21 +----
  22 +
  23 + === Occured ===
  24 + <%= notice.created_at.to_s(:micro) %>
  25 +
  26 +----
  27 +
  28 + === Similar ===
  29 + <%= (notice.problem.notices_count - 1).to_s %>
  30 +
  31 +----
  32 +
  33 + == Params ==
  34 +{{{
  35 +<%= pretty_hash(notice.params) %>
  36 +}}}
  37 +
  38 +----
  39 +
  40 + == Session ==
  41 +{{{
  42 +<%= pretty_hash(notice.session) %>
  43 +}}}
  44 +
  45 +----
  46 +
  47 + == Backtrace ==
  48 + <% for line in notice.backtrace %>| <%= line['number'] %>: | <%= line['file'].to_s.sub(/^\[PROJECT_ROOT\]/, '') %> -> **<%= line['method'] %>** |
  49 + <% end %>
  50 +
  51 +----
  52 +
  53 + == Environment ==
  54 + <% for key, val in notice.env_vars %>
  55 + | <%= key %>: | <%= val %> |
  56 + <% end %>
  57 +<% end %>
  58 +
... ...
spec/fabricators/issue_tracker_fabricator.rb
... ... @@ -24,3 +24,8 @@ Fabricator :github_issues_tracker, :from =&gt; :issue_tracker, :class_name =&gt; &quot;Issu
24 24 project_id 'test_account/test_project'
25 25 username 'test_username'
26 26 end
  27 +
  28 +Fabricator :bitbucket_issues_tracker, :from => :issue_tracker, :class_name => "IssueTrackers::BitbucketIssuesTracker" do
  29 + project_id 'password'
  30 + api_token 'test_username'
  31 +end
... ...
spec/models/issue_trackers/bitbucket_issues_tracker_spec.rb 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +require 'spec_helper'
  2 +
  3 +describe IssueTrackers::BitbucketIssuesTracker do
  4 + it "should create an issue on BitBucket Issues with problem params, and set issue link for problem" do
  5 + repo = "test_user/test_repo"
  6 + notice = Fabricate :notice
  7 + notice.app.bitbucket_repo = repo
  8 + tracker = Fabricate :bitbucket_issues_tracker, :app => notice.app
  9 + problem = notice.problem
  10 +
  11 + number = 123
  12 + @issue_link = "https://bitbucket.org/#{repo}/issue/#{number}/"
  13 + body = <<EOF
  14 +{
  15 + "status": "new",
  16 + "priority": "critical",
  17 + "title": "[production][foo#bar] FooError: Too Much Bar",
  18 + "comment_count": 0,
  19 + "content": "This is the content",
  20 + "created_on": "2012-07-29 04:35:38",
  21 + "local_id": 123,
  22 + "follower_count": 0,
  23 + "utc_created_on": "2012-07-29 02:35:38+00:00",
  24 + "resource_uri": "/1.0/repositories/test_user/test_repo/issue/123/",
  25 + "is_spam": false
  26 +}
  27 +EOF
  28 +
  29 + stub_request(:post, "https://#{tracker.api_token}:#{tracker.project_id}@bitbucket.org/api/1.0/repositories/test_username/test_repo/issues/").to_return(:status => 200, :headers => {}, :body => body )
  30 +
  31 + problem.app.issue_tracker.create_issue(problem)
  32 + problem.reload
  33 +
  34 + requested = have_requested(:post, "https://#{tracker.api_token}:#{tracker.project_id}@bitbucket.org/api/1.0/repositories/test_username/test_repo/issues/")
  35 + WebMock.should requested.with(:title => /[production][foo#bar] FooError: Too Much Bar/)
  36 + WebMock.should requested.with(:content => /See this exception on Errbit/)
  37 +
  38 + problem.issue_link.should == @issue_link
  39 + end
  40 +end
  41 +
... ...