Commit 5a59cc4f4fec2eaba069c612d4964f91c56e55e8

Authored by Sergey Kuznetsov
2 parents 88c83a71 d0e1a683
Exists in master and in 1 other branch production

Merge remote-tracking branch 'upstream/master'

@@ -36,6 +36,8 @@ gem 'pivotal-tracker' @@ -36,6 +36,8 @@ gem 'pivotal-tracker'
36 gem 'ruby-fogbugz', :require => 'fogbugz' 36 gem 'ruby-fogbugz', :require => 'fogbugz'
37 # Github Issues 37 # Github Issues
38 gem 'octokit', '~> 1.0.0' 38 gem 'octokit', '~> 1.0.0'
  39 +# Gitlab
  40 +gem 'gitlab'
39 41
40 # Bitbucket Issues 42 # Bitbucket Issues
41 gem 'bitbucket_rest_api' 43 gem 'bitbucket_rest_api'
@@ -81,6 +83,8 @@ group :development, :test do @@ -81,6 +83,8 @@ group :development, :test do
81 gem 'capistrano' 83 gem 'capistrano'
82 end 84 end
83 85
  86 +gem 'foreman', :group => :development
  87 +
84 group :test do 88 group :test do
85 gem 'capybara' 89 gem 'capybara'
86 gem 'launchy' 90 gem 'launchy'
@@ -97,6 +97,10 @@ GEM @@ -97,6 +97,10 @@ GEM
97 faraday_middleware (0.8.8) 97 faraday_middleware (0.8.8)
98 faraday (>= 0.7.4, < 0.9) 98 faraday (>= 0.7.4, < 0.9)
99 ffi (1.1.4) 99 ffi (1.1.4)
  100 + foreman (0.60.2)
  101 + thor (>= 0.13.6)
  102 + gitlab (2.1.0)
  103 + httparty
100 haml (3.1.6) 104 haml (3.1.6)
101 happymapper (0.4.0) 105 happymapper (0.4.0)
102 libxml-ruby (~> 2.0) 106 libxml-ruby (~> 2.0)
@@ -334,6 +338,8 @@ DEPENDENCIES @@ -334,6 +338,8 @@ DEPENDENCIES
334 email_spec 338 email_spec
335 execjs 339 execjs
336 fabrication (~> 1.3.0) 340 fabrication (~> 1.3.0)
  341 + foreman
  342 + gitlab
337 haml 343 haml
338 hipchat 344 hipchat
339 hoi 345 hoi
1 -web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb 1 +web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
@@ -383,6 +383,13 @@ card_type = Defect, status = Open, priority = Essential @@ -383,6 +383,13 @@ card_type = Defect, status = Open, priority = Essential
383 * For 'BITBUCKET REPO' field, the account will either be a username or organization. i.e. **errbit/errbit** 383 * For 'BITBUCKET REPO' field, the account will either be a username or organization. i.e. **errbit/errbit**
384 * You will also need to provide your username and password for your Bitbucket account. 384 * You will also need to provide your username and password for your Bitbucket account.
385 385
  386 +**Gitlab Issues Integration**
  387 +
  388 +* Account is the host of your gitlab installation. i.e. **http://gitlab.example.com**
  389 +* To authenticate, Errbit uses token-based authentication. Get your API Key in your user settings (or create special user for this purpose)
  390 +* You also need to provide project name (shortname) or ID (number) for issues to be created
  391 +* **Currently (as of 3.0), Gitlab has 2000 character limit for issue description.** It is necessary to turn it off at your instance, because Errbit issues body is much longer. Please comment validation line in issue model in models folder https://github.com/gitlabhq/gitlabhq/blob/master/app/models/issue.rb#L10
  392 +
386 393
387 394
388 What if Errbit has an error? 395 What if Errbit has an error?
app/assets/images/gitlab_create.png 0 → 100644

4.47 KB

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

4.47 KB

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

4.35 KB

app/models/issue_trackers/gitlab_tracker.rb 0 → 100644
@@ -0,0 +1,43 @@ @@ -0,0 +1,43 @@
  1 +if defined? Gitlab
  2 + class IssueTrackers::GitlabTracker < IssueTracker
  3 + Label = "gitlab"
  4 + Fields = [
  5 + [:account, {
  6 + :label => "Gitlab URL",
  7 + :placeholder => "e.g. https://example.net"
  8 + }],
  9 + [:api_token, {
  10 + :placeholder => "API Token for your account"
  11 + }],
  12 + [:project_id, {
  13 + :label => "Ticket Project Short Name / ID",
  14 + :placeholder => "Gitlab Project where issues will be created"
  15 + }]
  16 + ]
  17 +
  18 + def check_params
  19 + if Fields.detect {|f| self[f[0]].blank?}
  20 + errors.add :base, 'You must specify your Gitlab URL, API token and Project ID'
  21 + end
  22 + end
  23 +
  24 + def create_issue(problem, reported_by = nil)
  25 + Gitlab.configure do |config|
  26 + config.endpoint = "#{account}/api/v2"
  27 + config.private_token = api_token
  28 + config.user_agent = 'Errbit User Agent'
  29 + end
  30 + title = issue_title problem
  31 + description = body_template.result(binding)
  32 + Gitlab.create_issue(project_id, title, { :description => description, :labels => "errbit" } )
  33 + end
  34 +
  35 + def body_template
  36 + @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/gitlab_body.txt.erb").gsub(/^\s*/, ''))
  37 + end
  38 +
  39 + def url
  40 + "#{account}/#{project_id}/issues"
  41 + end
  42 + end
  43 +end
app/views/issue_trackers/gitlab_body.txt.erb 0 → 100644
@@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
  1 +[See this exception on Errbit](<%= app_problem_url problem.app, problem %> "See this exception on Errbit")
  2 +<% if notice = problem.notices.first %>
  3 +# <%= notice.message %> #
  4 +## Summary ##
  5 +<% if notice.request['url'].present? %>
  6 + ### URL ###
  7 + [<%= notice.request['url'] %>](<%= notice.request['url'] %>)"
  8 +<% end %>
  9 +### Where ###
  10 +<%= notice.where %>
  11 +
  12 +### Occured ###
  13 +<%= notice.created_at.to_s(:micro) %>
  14 +
  15 +### Similar ###
  16 +<%= (notice.problem.notices_count - 1).to_s %>
  17 +
  18 +## Params ##
  19 +```
  20 +<%= pretty_hash(notice.params) %>
  21 +```
  22 +
  23 +## Session ##
  24 +```
  25 +<%= pretty_hash(notice.session) %>
  26 +```
  27 +
  28 +## Backtrace ##
  29 +```
  30 +<% notice.backtrace_lines.each do |line| %><%= line.number %>: <%= line.file_relative %> -> **<%= line.method %>**
  31 +<% end %>
  32 +```
  33 +
  34 +## Environment ##
  35 +
  36 +<table>
  37 +<% for key, val in notice.env_vars %>
  38 + <tr>
  39 + <td><%= key %>:</td>
  40 + <td><%= val %></td>
  41 + </tr>
  42 +<% end %>
  43 +</table>
  44 +<% end %>
  45 +
spec/fabricators/issue_tracker_fabricator.rb
@@ -15,6 +15,10 @@ Fabricator :redmine_tracker, :from =&gt; :issue_tracker, :class_name =&gt; &quot;IssueTrack @@ -15,6 +15,10 @@ Fabricator :redmine_tracker, :from =&gt; :issue_tracker, :class_name =&gt; &quot;IssueTrack
15 account 'http://redmine.example.com' 15 account 'http://redmine.example.com'
16 end 16 end
17 17
  18 +Fabricator :gitlab_tracker, :from => :issue_tracker, :class_name => "IssueTrackers::GitlabTracker" do
  19 + account 'http://gitlab.example.com'
  20 +end
  21 +
18 Fabricator :mingle_tracker, :from => :issue_tracker, :class_name => "IssueTrackers::MingleTracker" do 22 Fabricator :mingle_tracker, :from => :issue_tracker, :class_name => "IssueTrackers::MingleTracker" do
19 account 'https://mingle.example.com' 23 account 'https://mingle.example.com'
20 ticket_properties 'card_type = Defect, defect_status = open, priority = essential' 24 ticket_properties 'card_type = Defect, defect_status = open, priority = essential'
spec/models/issue_trackers/github_issues_tracker_spec 2.rb 0 → 100644
@@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
  1 +require 'spec_helper'
  2 +
  3 +describe IssueTrackers::GitlabTracker do
  4 + it "should create an issue on Gitlab with problem params" do
  5 + notice = Fabricate :notice
  6 + tracker = Fabricate :gitlab_tracker, :app => notice.app
  7 + problem = notice.problem
  8 +
  9 + number = 5
  10 + @issue_link = "#{tracker.account}/#{tracker.project_id}/issues/#{number}/#{tracker.api_token}"
  11 + body = <<EOF
  12 +{
  13 + "title": "Title"
  14 +}
  15 +EOF
  16 +
  17 + stub_request(:post, "#{tracker.account}/#{tracker.project_id}/issues/#{tracker.api_token}").
  18 + to_return(:status => 201, :headers => {'Location' => @issue_link}, :body => body )
  19 +
  20 + problem.app.issue_tracker.create_issue(problem)
  21 + problem.reload
  22 +
  23 + requested = have_requested(:post, "#{tracker.account}/#{tracker.project_id}/issues/#{tracker.api_token}")
  24 + WebMock.should requested.with(:body => /[production][foo#bar] FooError: Too Much Bar/)
  25 + WebMock.should requested.with(:body => /See this exception on Errbit/)
  26 +
  27 + problem.issue_link.should == @issue_link
  28 + end
  29 +end
  30 +