From 901d8526f316e8c2cf1bea151e180b04f0148a22 Mon Sep 17 00:00:00 2001 From: Danil Tashkinov Date: Fri, 6 Jun 2014 16:02:54 +0400 Subject: [PATCH] Added ability to fetch_repositories by web hook from bitbucket --- app/controllers/undev_git_hooks_controller.rb | 8 ++++ .../settings/_web_hooks_description.html.erb | 6 +++ config/routes.rb | 1 + lib/redmine_undev_git.rb | 5 ++- lib/redmine_undev_git/services/bitbucket.rb | 42 ++++++++++++++++++ .../receive_external_hooks_test.rb | 44 +++++++++++++++++++ 6 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 lib/redmine_undev_git/services/bitbucket.rb diff --git a/app/controllers/undev_git_hooks_controller.rb b/app/controllers/undev_git_hooks_controller.rb index dbb0413..dd03a37 100644 --- a/app/controllers/undev_git_hooks_controller.rb +++ b/app/controllers/undev_git_hooks_controller.rb @@ -21,6 +21,14 @@ def github_push head :bad_request end + def bitbucket_push + urls = RedmineUndevGit::Services::Bitbucket.git_urls_from_request(request) + fetch_repositories(urls) + head :ok + rescue RedmineUndevGit::Services::ServiceError + head :bad_request + end + private def fetch_repositories(urls) diff --git a/app/views/settings/_web_hooks_description.html.erb b/app/views/settings/_web_hooks_description.html.erb index 9ab3381..16ad93d 100644 --- a/app/views/settings/_web_hooks_description.html.erb +++ b/app/views/settings/_web_hooks_description.html.erb @@ -11,5 +11,11 @@ github_hooks_url(:host => Setting.host_name, :protocol => Setting.protocol), :size => 60, :readonly => true, + :class => 'web-hook-url' %>
+ Bitbucket webhook url: + <%= text_field_tag 'bitbucket-web-hook', + bitbucket_hooks_url(:host => Setting.host_name, :protocol => Setting.protocol), + :size => 60, + :readonly => true, :class => 'web-hook-url' %> diff --git a/config/routes.rb b/config/routes.rb index aa17724..56b73fb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -7,4 +7,5 @@ match 'gitlab_hooks' => 'undev_git_hooks#gitlab_push', :via => :post, :as => :gitlab_hooks match 'github_hooks' => 'undev_git_hooks#github_push', :via => :post, :as => :github_hooks + match 'bitbucket_hooks' => 'undev_git_hooks#bitbucket_push', :via => :post, :as => :bitbucket_hooks end diff --git a/lib/redmine_undev_git.rb b/lib/redmine_undev_git.rb index a262d56..17b3c9e 100644 --- a/lib/redmine_undev_git.rb +++ b/lib/redmine_undev_git.rb @@ -32,9 +32,12 @@ def self.fetch_by_web_hook=(value) require 'redmine_undev_git/hooks/view_hooks' -require 'redmine_undev_git/services/errors' require 'redmine_undev_git/services/migration' +require 'redmine_undev_git/services/errors' +require 'redmine_undev_git/services/ext_repo' require 'redmine_undev_git/services/gitlab' +require 'redmine_undev_git/services/github' +require 'redmine_undev_git/services/bitbucket' require 'redmine_undev_git/patches/redmine_scm_base_patch' require 'redmine_undev_git/patches/custom_field_patch' diff --git a/lib/redmine_undev_git/services/bitbucket.rb b/lib/redmine_undev_git/services/bitbucket.rb new file mode 100644 index 0000000..fca33ac --- /dev/null +++ b/lib/redmine_undev_git/services/bitbucket.rb @@ -0,0 +1,42 @@ +module RedmineUndevGit::Services + class BitbucketRepo < ExtRepo + attr_reader :repo_owner + def initialize(absolute_url, canon_url, repo_owner) + if m = /\Ahttps?:\/\/(?.+?)\z/.match(canon_url) + @host = m[:host] + else + raise RedmineUndevGit::Services::WrongRepoUrl + end + if m = /\A\/(?.+)\/\z/.match(absolute_url) + @path_to_repo = m[:path_to_repo] + else + raise RedmineUndevGit::Services::WrongRepoUrl + end + @user = 'git' + @repo_owner = repo_owner + end + + def git_urls + [ssh_url, https_url, https_with_owner_url] + end + + def https_with_owner_url + "https://#{repo_owner}@#{host}/#{path_to_repo}.git" + end + end + + class Bitbucket + class << self + def git_urls_from_request(request) + web_hook = web_hook_from_request(request) + repo = RedmineUndevGit::Services::BitbucketRepo.new( + web_hook['repository']['absolute_url'], web_hook['canon_url'], web_hook['user']) + repo.git_urls + end + + def web_hook_from_request(request) + JSON.parse(request.params[:payload]) + end + end + end +end diff --git a/test/integration/receive_external_hooks_test.rb b/test/integration/receive_external_hooks_test.rb index 2d330b7..fc89497 100644 --- a/test/integration/receive_external_hooks_test.rb +++ b/test/integration/receive_external_hooks_test.rb @@ -42,6 +42,14 @@ def test_success_on_github_ping_hook_when_login_requred assert_response :success end + def test_fetch_after_bitbucket_push_hook + repository = create_test_repository(:project => @project, :url => 'https://bitbucket.org/test/dt_fetch.git') + assert repository + Workers::RepositoryFetcher.expects(:defer).with(repository.id).at_least_once + post '/bitbucket_hooks', :payload => bitbucket_payload.to_json + assert_response :success + end + def gitlab_payload { before: '95790bf891e76fee5e1747ab589903a6a1f80f22', @@ -259,4 +267,40 @@ def github_ping_headers 'HTTP_X_GITHUB_EVENT' => 'ping' } end + + def bitbucket_payload + { + repository: { + website: '', + fork: false, + name: 'dt_fetch', + scm: 'git', + owner: 'test', + absolute_url: '/test/dt_fetch/', + slug: 'dt_fetch', + is_private: false + }, + truncated: false, + commits: [ + { + node: '81c83664d120', + files: [ + {type: 'added', file: 'update5.txt'} + ], + raw_author: 'Test ', + utctimestamp: '2014-06-06 07:04:38+00:00', + author: 'test', + timestamp: '2014-06-06 09:04:38', + raw_node: '81c83664d120ce05c91b7259b70c02ebc64edd52', + parents: ['75d5e5aef45a'], + branch: 'master', + message: 'update 5', + revision: nil, + size: -1 + } + ], + canon_url: 'https://bitbucket.org', + user: 'test' + } + end end