/lib/bitbucket.rb
Ruby | 112 lines | 86 code | 19 blank | 7 comment | 3 complexity | 91d4906e13d9773b55fdcca573df58c1 MD5 | raw file
- # coding: utf-8
- require 'yaml'
- require 'json'
- require 'bitbucket-api-extension'
- class PullRequestTester
- attr_accessor :config
- attr_reader :bitbucket
- def initialize(config_path)
- @config = YAML.load_file(config_path)
- setup_bitbucket!
- end
- def run
- target = fetch_pullrequest
- if target
- detail = @bitbucket.pull_request_detail(target)
- branch_or_commit_id = detail.from_commit_id || detail.from_branch_name
- exec_spec(detail.from_user_or_team_name, detail.from_repository_name, branch_or_commit_id)
- write_result_to_pullrequest(false, detail)
- end
- # cleanup
- end
- def fetch_pullrequest
- @bitbucket.pull_requests
- .reject { |request|
- comments = @bitbucket.pull_request_comment(request)
- comments.any? { |c| c.try(:comment).try(:include?, "[TestComplete]") } }
- .first
- end
- def exec_spec(team_name, repository, revision)
- commands =
- ["hg pull ssh://hg@bitbucket.org/#{team_name}/#{repository} -r '#{revision}'",
- "hg up -r #{revision}",
- "bundle install",
- "bundle exec rake db:cp",
- "bundle exec rake db:drop db:create db:migrate RAILS_ENV=test",
- "bundle exec rspec --format json --out #{@config['spec']['result_path']}"]
- Dir.chdir(@config['local_repository_path']) do
- commands.each do |command|
- puts "execute command -> #{command}"
- system(command)
- end
- end
- end
- def write_result_to_pullrequest(success, target)
- message = RSpecReporter.new.report(open("#{@config['spec']['result_path']}").read)
- @bitbucket.post_comment(target, message)
- end
- def cleanup
- system("rm #{@config['spec']['result_path']}")
- end
- private
- def setup_bitbucket!
- project = BitbucketApiExtension::Project.new(name: @config['bitbucket']['repository_name'],
- organization_name: @config['bitbucket']['team'])
- account = BitbucketApiExtension::Account.new(user_id: @config['bitbucket']['id'],
- user_password: @config['bitbucket']['password'])
- @bitbucket = BitbucketApiExtension::Api.new(project, account)
- end
- end
- class RSpecReporter
- # return [成功失敗, コメント用メッセージ]
- def report(log)
- result = JSON.parse(log)
- success = result['summary']['failure_count'].to_i == 0
- summary = <<-EOF
- ```
- [TestComplete] テストに#{success ? "成功" : "失敗"}しました。
- #{success ? "" : "このプルリクエストを取り込むとテストに失敗する可能性があります。"}
- テスト実行に #{result['summary']['duration']} sec かかりました。
- Example Count: #{result['summary']['example_count']}
- Failure Count: #{result['summary']['failure_count']}
- Pending Count: #{result['summary']['pending_count']}
- EOF
- failure_message = result['examples']
- .reject { |exp| exp['exception'].nil? }
- .each_with_index
- .map { |exp, index|
- description = exp['full_description']
- file_path = exp['file_path']
- message = exp['exception']['message']
- # backtrace = exp['exception']['backtrace'].join("\n")
- <<-EOF
- #{index + 1}: #{description}
- 対象ファイル: #{file_path}
- エラーメッセージ:
- #{message}
- EOF
- }
- .join("\n\n")
- failure_message += "```"
- "#{summary}\n#{failure_message}"
- end
- end