Commit 392b7b9c2ce816d73ac5f21a1f217f13dd8400d5
1 parent
3db48ca3
Exists in
master
and in
1 other branch
adding support for Bitbucket issues with tests + small fix for gtalk icon
Conflicts: Gemfile app/assets/images/gtalk_inactive.png
Showing
10 changed files
with
164 additions
and
1 deletions
Show diff stats
Gemfile
... | ... | @@ -33,10 +33,13 @@ gem 'rack-ssl-enforcer' |
33 | 33 | gem 'fabrication', "~> 1.3.0" # Both for tests, and loading demo data |
34 | 34 | gem 'rails_autolink', '~> 1.0.9' |
35 | 35 | gem 'campy' |
36 | +gem 'xmpp4r' | |
37 | +gem 'hipchat-api' | |
38 | +gem 'bitbucket_rest_api' | |
36 | 39 | |
37 | 40 | # Please don't update this to airbrake - We override the send_notice method |
38 | 41 | # to handle internal errors. |
39 | -gem 'hoptoad_notifier', "~> 2.4" | |
42 | +gem 'hoptoad_notifier', '~> 2.4' | |
40 | 43 | |
41 | 44 | platform :ruby do |
42 | 45 | gem 'mongo', '= 1.6.2' | ... | ... |
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) |
... | ... | @@ -256,6 +263,7 @@ GEM |
256 | 263 | libwebsocket (~> 0.1.3) |
257 | 264 | multi_json (~> 1.0) |
258 | 265 | rubyzip |
266 | + simple_oauth (0.1.9) | |
259 | 267 | slop (2.4.4) |
260 | 268 | sprockets (2.1.3) |
261 | 269 | hike (~> 1.2) |
... | ... | @@ -297,6 +305,7 @@ PLATFORMS |
297 | 305 | DEPENDENCIES |
298 | 306 | SystemTimer |
299 | 307 | actionmailer_inline_css (~> 1.3.0) |
308 | + bitbucket_rest_api | |
300 | 309 | bson (= 1.6.2) |
301 | 310 | bson_ext (= 1.6.2) |
302 | 311 | campy | ... | ... |
2.54 KB
3.61 KB
1.95 KB
1.91 KB
... | ... | @@ -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 | + | ... | ... |
... | ... | @@ -0,0 +1,58 @@ |
1 | +[[<%= app_err_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 => :issue_tracker, :class_name => "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 | + | ... | ... |