PageRenderTime 62ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/bitbucket.rb

https://bitbucket.org/snishio/prtester
Ruby | 112 lines | 86 code | 19 blank | 7 comment | 3 complexity | 91d4906e13d9773b55fdcca573df58c1 MD5 | raw file
  1. # coding: utf-8
  2. require 'yaml'
  3. require 'json'
  4. require 'bitbucket-api-extension'
  5. class PullRequestTester
  6. attr_accessor :config
  7. attr_reader :bitbucket
  8. def initialize(config_path)
  9. @config = YAML.load_file(config_path)
  10. setup_bitbucket!
  11. end
  12. def run
  13. target = fetch_pullrequest
  14. if target
  15. detail = @bitbucket.pull_request_detail(target)
  16. branch_or_commit_id = detail.from_commit_id || detail.from_branch_name
  17. exec_spec(detail.from_user_or_team_name, detail.from_repository_name, branch_or_commit_id)
  18. write_result_to_pullrequest(false, detail)
  19. end
  20. # cleanup
  21. end
  22. def fetch_pullrequest
  23. @bitbucket.pull_requests
  24. .reject { |request|
  25. comments = @bitbucket.pull_request_comment(request)
  26. comments.any? { |c| c.try(:comment).try(:include?, "[TestComplete]") } }
  27. .first
  28. end
  29. def exec_spec(team_name, repository, revision)
  30. commands =
  31. ["hg pull ssh://hg@bitbucket.org/#{team_name}/#{repository} -r '#{revision}'",
  32. "hg up -r #{revision}",
  33. "bundle install",
  34. "bundle exec rake db:cp",
  35. "bundle exec rake db:drop db:create db:migrate RAILS_ENV=test",
  36. "bundle exec rspec --format json --out #{@config['spec']['result_path']}"]
  37. Dir.chdir(@config['local_repository_path']) do
  38. commands.each do |command|
  39. puts "execute command -> #{command}"
  40. system(command)
  41. end
  42. end
  43. end
  44. def write_result_to_pullrequest(success, target)
  45. message = RSpecReporter.new.report(open("#{@config['spec']['result_path']}").read)
  46. @bitbucket.post_comment(target, message)
  47. end
  48. def cleanup
  49. system("rm #{@config['spec']['result_path']}")
  50. end
  51. private
  52. def setup_bitbucket!
  53. project = BitbucketApiExtension::Project.new(name: @config['bitbucket']['repository_name'],
  54. organization_name: @config['bitbucket']['team'])
  55. account = BitbucketApiExtension::Account.new(user_id: @config['bitbucket']['id'],
  56. user_password: @config['bitbucket']['password'])
  57. @bitbucket = BitbucketApiExtension::Api.new(project, account)
  58. end
  59. end
  60. class RSpecReporter
  61. # return [成功失敗, コメント用メッセージ]
  62. def report(log)
  63. result = JSON.parse(log)
  64. success = result['summary']['failure_count'].to_i == 0
  65. summary = <<-EOF
  66. ```
  67. [TestComplete] テストに#{success ? "成功" : "失敗"}しました。
  68. #{success ? "" : "このプルリクエストを取り込むとテストに失敗する可能性があります。"}
  69. テスト実行に #{result['summary']['duration']} sec かかりました。
  70. Example Count: #{result['summary']['example_count']}
  71. Failure Count: #{result['summary']['failure_count']}
  72. Pending Count: #{result['summary']['pending_count']}
  73. EOF
  74. failure_message = result['examples']
  75. .reject { |exp| exp['exception'].nil? }
  76. .each_with_index
  77. .map { |exp, index|
  78. description = exp['full_description']
  79. file_path = exp['file_path']
  80. message = exp['exception']['message']
  81. # backtrace = exp['exception']['backtrace'].join("\n")
  82. <<-EOF
  83. #{index + 1}: #{description}
  84. 対象ファイル: #{file_path}
  85. エラーメッセージ:
  86. #{message}
  87. EOF
  88. }
  89. .join("\n\n")
  90. failure_message += "```"
  91. "#{summary}\n#{failure_message}"
  92. end
  93. end