From 1094e31ff03238a57c7a5fbac0483f35870c4c41 Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Thu, 16 May 2013 12:06:16 -0600 Subject: [PATCH 01/16] Create SAPDshell.rb --- lib/services/SAPDshell.rb | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 lib/services/SAPDshell.rb diff --git a/lib/services/SAPDshell.rb b/lib/services/SAPDshell.rb new file mode 100644 index 000000000..e1b64be7f --- /dev/null +++ b/lib/services/SAPDshell.rb @@ -0,0 +1,4 @@ +class Service::SAPD shell < Service + def receive_push + end +end From 1d052b148b4a7b2fd9f4a0268f76d957a6e53e8a Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Thu, 16 May 2013 12:08:58 -0600 Subject: [PATCH 02/16] Update SAPDshell.rb --- lib/services/SAPDshell.rb | 109 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/lib/services/SAPDshell.rb b/lib/services/SAPDshell.rb index e1b64be7f..30db0a184 100644 --- a/lib/services/SAPDshell.rb +++ b/lib/services/SAPDshell.rb @@ -1,4 +1,113 @@ class Service::SAPD shell < Service + string :dshell_url, :user_id + password :password + white_list :space_id, :user_id + def receive_push + if data['dshell_url'].to_s.empty? + raise_config_error "SAP Dshell URL not set" + end + if data['user_id'].to_s.empty? + raise_config_error "user_id not set" + end + if data['password'].to_s.empty? + raise_config_error "password not set" + end + + repository = payload['repository']['url'].to_s + commits = payload['commits'].collect{|c| Commit.new(c)} + issue_commits = sort_commits(commits) + issue_commits.sort.map do | issue, commits | + post(issue, repository, commits, branch.to_s) + end + + end + + def branch + return @branch if defined?(@branch) + + matches = payload['ref'].match(/^refs\/heads\/(.*)$/) + @branch = matches ? matches[1] : nil + end + + attr_writer :xmlrpc_client + def xmlrpc_client + @xmlrpc_client ||= begin + uri = data['api_url'].to_s.sub('https://', "https://#{data['user_id'].to_s}:#{data['password'].to_s}@") + client = XMLRPC::Client.new2(uri) + # call for auth check + client.call('backlog.getProjects') + client + rescue XMLRPC::FaultException + raise_config_error "Invalid login details" + rescue SocketError, RuntimeError + raise_config_error "Invalid server url" + end + end + + def sort_commits(commits) + issue_commits = Hash.new{|k,v| k[v] = []} + commits.each do |commit| + commit.issue.each do |issue| + issue_commits[issue] << commit + end + end + return issue_commits + end + + def post(issue, repository, commits, branch_name) + if commits.length == 0 + return + end + + branch_str = branch_name.empty? ? "" : "#{branch_name} at " + message = "pushed to #{branch_str}#{repository}\n\n" + + commits.each do |commit| + comment = "#{message}#{commit.comment}" + begin + if commit.status + xmlrpc_client.call('backlog.switchStatus', {'key' => issue, 'statusId' => commit.status, 'comment' => comment}) + else + xmlrpc_client.call('backlog.addComment', {'key' => issue, 'content' => comment}) + end + rescue XMLRPC::FaultException + raise_config_error "failed post" + rescue RuntimeError + raise_config_error "failed post" + end + end + end + + class Commit + attr_reader :status, :issue, :url, :id + + def initialize(commit_hash) + @id = commit_hash['id'].to_s + @url = commit_hash['url'].to_s + @message = commit_hash['message'].to_s + @status = nil + @issue = [] + + re_issue_key = /(?:\[\[)?(([A-Z0-9]+(?:_[A-Z0-9]+)*)-([1-9][0-9]*))(?:\]\])?/ + temp = @message + while temp =~ re_issue_key + issue << $1 + temp.sub!($1, '') + end + + re_status = /(?:^|\s+?)(#fixes|#fixed|#fix|#closes|#closed|#close)(?:\s+?|$)/ + while @message =~ re_status + switch = $1 + @message.sub!(switch, '') + @status = (switch =~ /fix/) ? 3 : 4 + end + end + + def comment() + output = "#{@url}\n" + output += @message.strip + return output + end end end From 9877b943b78bdfbdb5c98c5e83255e3f3114e63c Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Thu, 16 May 2013 13:55:10 -0600 Subject: [PATCH 03/16] Create SAPDshell --- docs/SAPDshell | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 docs/SAPDshell diff --git a/docs/SAPDshell b/docs/SAPDshell new file mode 100644 index 000000000..a7351fca2 --- /dev/null +++ b/docs/SAPDshell @@ -0,0 +1,19 @@ +SAPDshell +========= + +The SAP HANA Deployment shell (Dshell) is a cloud-hosted service provided by SAP for developers to deploy HTML and JavaScript sources to SAP HANA development edition. + +Integrating with GitHub will allow you to associate Git commits to specific HANA database. + + +Install Notes +------------- + +1. **DShell URL** - This is the DShell instance you are using +2. **User** - This is the user on your HANA instance. +3. **Password** - This is your Passowrd on the HANA instance. + +Need Help? +---------- + +Check out our [step by step instructions](http://scn.sap.com/docs/DOC-41137). From c7de0e4ea6e5f9ab4f433bef539f6a7ef0a2c6bd Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Thu, 16 May 2013 14:00:01 -0600 Subject: [PATCH 04/16] Update SAPDshell.rb --- lib/services/SAPDshell.rb | 132 +++++++++++--------------------------- 1 file changed, 38 insertions(+), 94 deletions(-) diff --git a/lib/services/SAPDshell.rb b/lib/services/SAPDshell.rb index 30db0a184..b2cd169a4 100644 --- a/lib/services/SAPDshell.rb +++ b/lib/services/SAPDshell.rb @@ -1,9 +1,24 @@ -class Service::SAPD shell < Service +class Service::SAPDshell < Service string :dshell_url, :user_id password :password white_list :space_id, :user_id + + url "http://dshell.saphana.com" + logo_url "http://www.sap.com/global/ui/images/global/sap-logo.png" + + # SAPDshell on GitHub is pinged for any bugs with the Hook code. + maintained_by :github => 'SAPDshell' + + # Support channels for user-level Hook problems (service failure, + # misconfigured + supported_by :web => 'http://scn.sap.com/community/developer-center/content', + :email => 'dshell@sap.com' + + def receive_push + + # Check for settings if data['dshell_url'].to_s.empty? raise_config_error "SAP Dshell URL not set" end @@ -13,101 +28,30 @@ def receive_push if data['password'].to_s.empty? raise_config_error "password not set" end - + + # Sets this basic auth info for every request. + http.basic_auth(data['user_id'], data['password']) + + http.headers['Content-Type'] = 'application/json' + + # Uses this URL as a prefix for every request. + http.url_prefix = "https://" + + repository = payload['repository']['url'].to_s - commits = payload['commits'].collect{|c| Commit.new(c)} - issue_commits = sort_commits(commits) - issue_commits.sort.map do | issue, commits | - post(issue, repository, commits, branch.to_s) - end + dshell_url = data['dshell_url'] + + call_url = "{dshell_url}/?repo={repository}" + + res = http_post call_url - end - - def branch - return @branch if defined?(@branch) - - matches = payload['ref'].match(/^refs\/heads\/(.*)$/) - @branch = matches ? matches[1] : nil - end - - attr_writer :xmlrpc_client - def xmlrpc_client - @xmlrpc_client ||= begin - uri = data['api_url'].to_s.sub('https://', "https://#{data['user_id'].to_s}:#{data['password'].to_s}@") - client = XMLRPC::Client.new2(uri) - # call for auth check - client.call('backlog.getProjects') - client - rescue XMLRPC::FaultException - raise_config_error "Invalid login details" - rescue SocketError, RuntimeError - raise_config_error "Invalid server url" - end - end - - def sort_commits(commits) - issue_commits = Hash.new{|k,v| k[v] = []} - commits.each do |commit| - commit.issue.each do |issue| - issue_commits[issue] << commit - end + if res.status < 200 || res.status > 299 + raise_config_error "Failed with #{res.status}" end - return issue_commits - end - def post(issue, repository, commits, branch_name) - if commits.length == 0 - return - end - - branch_str = branch_name.empty? ? "" : "#{branch_name} at " - message = "pushed to #{branch_str}#{repository}\n\n" - - commits.each do |commit| - comment = "#{message}#{commit.comment}" - begin - if commit.status - xmlrpc_client.call('backlog.switchStatus', {'key' => issue, 'statusId' => commit.status, 'comment' => comment}) - else - xmlrpc_client.call('backlog.addComment', {'key' => issue, 'content' => comment}) - end - rescue XMLRPC::FaultException - raise_config_error "failed post" - rescue RuntimeError - raise_config_error "failed post" - end - end - end - - class Commit - attr_reader :status, :issue, :url, :id - - def initialize(commit_hash) - @id = commit_hash['id'].to_s - @url = commit_hash['url'].to_s - @message = commit_hash['message'].to_s - @status = nil - @issue = [] - - re_issue_key = /(?:\[\[)?(([A-Z0-9]+(?:_[A-Z0-9]+)*)-([1-9][0-9]*))(?:\]\])?/ - temp = @message - while temp =~ re_issue_key - issue << $1 - temp.sub!($1, '') - end - - re_status = /(?:^|\s+?)(#fixes|#fixed|#fix|#closes|#closed|#close)(?:\s+?|$)/ - while @message =~ re_status - switch = $1 - @message.sub!(switch, '') - @status = (switch =~ /fix/) ? 3 : 4 - end - end - - def comment() - output = "#{@url}\n" - output += @message.strip - return output - end - end + rescue URI::InvalidURIError + raise_config_error "Invalid URL: #{call_url}" + + + end From f44c38a4006415ce554197d4aa23c63d15812074 Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Thu, 16 May 2013 15:16:37 -0600 Subject: [PATCH 05/16] Update SAPDshell.rb --- lib/services/SAPDshell.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/services/SAPDshell.rb b/lib/services/SAPDshell.rb index b2cd169a4..875cefbce 100644 --- a/lib/services/SAPDshell.rb +++ b/lib/services/SAPDshell.rb @@ -23,16 +23,16 @@ def receive_push raise_config_error "SAP Dshell URL not set" end if data['user_id'].to_s.empty? - raise_config_error "user_id not set" + raise_config_error "User id not set" end if data['password'].to_s.empty? - raise_config_error "password not set" + raise_config_error "Password not set" end # Sets this basic auth info for every request. http.basic_auth(data['user_id'], data['password']) - http.headers['Content-Type'] = 'application/json' + # http.headers['Content-Type'] = 'application/json' # Uses this URL as a prefix for every request. http.url_prefix = "https://" From eef8941146fb6baa01956d99cfded848d134781f Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Thu, 16 May 2013 15:42:15 -0600 Subject: [PATCH 06/16] Update SAPDshell --- docs/SAPDshell | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/SAPDshell b/docs/SAPDshell index a7351fca2..f2fb7938d 100644 --- a/docs/SAPDshell +++ b/docs/SAPDshell @@ -9,7 +9,7 @@ Integrating with GitHub will allow you to associate Git commits to specific HANA Install Notes ------------- -1. **DShell URL** - This is the DShell instance you are using +1. **DShell URL** - This is the URL of the DShell instance and port you are using 2. **User** - This is the user on your HANA instance. 3. **Password** - This is your Passowrd on the HANA instance. From 88857be76b4e86fd7a81d9dfadd273429ea5470b Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Thu, 16 May 2013 16:34:28 -0600 Subject: [PATCH 07/16] Update SAPDshell.rb --- lib/services/SAPDshell.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/SAPDshell.rb b/lib/services/SAPDshell.rb index 875cefbce..64b798831 100644 --- a/lib/services/SAPDshell.rb +++ b/lib/services/SAPDshell.rb @@ -35,7 +35,7 @@ def receive_push # http.headers['Content-Type'] = 'application/json' # Uses this URL as a prefix for every request. - http.url_prefix = "https://" + http.url_prefix = "http://" repository = payload['repository']['url'].to_s From f298b654947a532647cdd334ca573c3958fc3321 Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Thu, 16 May 2013 16:35:08 -0600 Subject: [PATCH 08/16] Update SAPDshell.rb --- lib/services/SAPDshell.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/services/SAPDshell.rb b/lib/services/SAPDshell.rb index 64b798831..359ba658a 100644 --- a/lib/services/SAPDshell.rb +++ b/lib/services/SAPDshell.rb @@ -1,7 +1,6 @@ class Service::SAPDshell < Service string :dshell_url, :user_id password :password - white_list :space_id, :user_id url "http://dshell.saphana.com" From 2185ec704384d3d6a218b31c54973baf21728855 Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Thu, 16 May 2013 17:01:52 -0600 Subject: [PATCH 09/16] Update SAPDshell.rb --- lib/services/SAPDshell.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/SAPDshell.rb b/lib/services/SAPDshell.rb index 359ba658a..de1982328 100644 --- a/lib/services/SAPDshell.rb +++ b/lib/services/SAPDshell.rb @@ -42,7 +42,7 @@ def receive_push call_url = "{dshell_url}/?repo={repository}" - res = http_post call_url + res = http_post call_url, generate_json(payload) if res.status < 200 || res.status > 299 raise_config_error "Failed with #{res.status}" From c06809f2cea0521a42bfe284a0ce14688f023889 Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Tue, 21 May 2013 11:16:47 -0600 Subject: [PATCH 10/16] Update SAPDshell.rb --- lib/services/SAPDshell.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/SAPDshell.rb b/lib/services/SAPDshell.rb index de1982328..6b42d4352 100644 --- a/lib/services/SAPDshell.rb +++ b/lib/services/SAPDshell.rb @@ -52,5 +52,5 @@ def receive_push raise_config_error "Invalid URL: #{call_url}" - +end end From 4df1c951d2a25e5cbc6d3413543dec2b8ac920ca Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Tue, 21 May 2013 12:27:42 -0600 Subject: [PATCH 11/16] Update SAPDshell.rb --- lib/services/SAPDshell.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/SAPDshell.rb b/lib/services/SAPDshell.rb index 6b42d4352..630753380 100644 --- a/lib/services/SAPDshell.rb +++ b/lib/services/SAPDshell.rb @@ -40,7 +40,7 @@ def receive_push repository = payload['repository']['url'].to_s dshell_url = data['dshell_url'] - call_url = "{dshell_url}/?repo={repository}" + call_url = "#{dshell_url}/?repo=#{repository}" res = http_post call_url, generate_json(payload) From 1084869e41e197e0a1ef588396914c66a42c1a30 Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Wed, 22 May 2013 10:52:15 -0600 Subject: [PATCH 12/16] Create SAPDshell_test.rb --- test/SAPDshell_test.rb | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/SAPDshell_test.rb diff --git a/test/SAPDshell_test.rb b/test/SAPDshell_test.rb new file mode 100644 index 000000000..5fd2b40c0 --- /dev/null +++ b/test/SAPDshell_test.rb @@ -0,0 +1,25 @@ +require File.expand_path('../helper', __FILE__) + +class SAPDshellTest < Service::TestCase + def setup + @stubs = Faraday::Adapter::Test::Stubs.new + end + + def test_push + @stubs.post "/api/github/a" do |env| + assert_equal 'dshell.saphana.com', env[:url].host + data = Faraday::Utils.parse_query(env[:body]) + assert_equal payload.to_json, data['payload'] + [200, {}, ''] + end + + svc = service({'dshell_url' => 'dshell.saphana.com:30015', 'user_id' => 'system', 'password' => 'HANA2012' }, + payload) + svc.receive_push + + end + + def service(*args) + super Service::SAPDshell, *args + end +end From 837e981990720d56b3c816fb4334743c72c57fb3 Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Thu, 23 May 2013 16:21:33 -0600 Subject: [PATCH 13/16] Update SAPDshell.rb --- lib/services/SAPDshell.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/SAPDshell.rb b/lib/services/SAPDshell.rb index 630753380..5d56325ad 100644 --- a/lib/services/SAPDshell.rb +++ b/lib/services/SAPDshell.rb @@ -31,7 +31,7 @@ def receive_push # Sets this basic auth info for every request. http.basic_auth(data['user_id'], data['password']) - # http.headers['Content-Type'] = 'application/json' + http.headers['Content-Type'] = 'application/json' # Uses this URL as a prefix for every request. http.url_prefix = "http://" From e69d9468db021a756c85ba7a585500504f2b8fc4 Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Wed, 29 May 2013 10:26:48 -0600 Subject: [PATCH 14/16] Update SAPDshell.rb --- lib/services/SAPDshell.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/services/SAPDshell.rb b/lib/services/SAPDshell.rb index 5d56325ad..3bc803c13 100644 --- a/lib/services/SAPDshell.rb +++ b/lib/services/SAPDshell.rb @@ -37,19 +37,19 @@ def receive_push http.url_prefix = "http://" - repository = payload['repository']['url'].to_s - dshell_url = data['dshell_url'] + l_repository = payload['repository']['url'].to_s + l_dshell_url = data['dshell_url'] - call_url = "#{dshell_url}/?repo=#{repository}" + l_call_url = "#{l_dshell_url}/?repo=#{l_repository}" - res = http_post call_url, generate_json(payload) + res = http_post l_call_url, generate_json(payload) if res.status < 200 || res.status > 299 raise_config_error "Failed with #{res.status}" end rescue URI::InvalidURIError - raise_config_error "Invalid URL: #{call_url}" + raise_config_error "Invalid URL: #{l_call_url}" end From cfddac0fc7274d8bfc1076f191dbf45d9b3994b7 Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Fri, 7 Jun 2013 11:14:41 +0200 Subject: [PATCH 15/16] Update SAPDshell.rb --- lib/services/SAPDshell.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/SAPDshell.rb b/lib/services/SAPDshell.rb index 3bc803c13..135166d12 100644 --- a/lib/services/SAPDshell.rb +++ b/lib/services/SAPDshell.rb @@ -1,4 +1,4 @@ -class Service::SAPDshell < Service +class Service::SAPDshell < Service::HttpPost string :dshell_url, :user_id password :password From 71f6e9af28b9ad853865d50322a033071191a2b2 Mon Sep 17 00:00:00 2001 From: SAPDshell Date: Tue, 11 Jun 2013 11:52:14 -0600 Subject: [PATCH 16/16] Update SAPDshell.rb --- lib/services/SAPDshell.rb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/services/SAPDshell.rb b/lib/services/SAPDshell.rb index 135166d12..e4724d265 100644 --- a/lib/services/SAPDshell.rb +++ b/lib/services/SAPDshell.rb @@ -15,21 +15,21 @@ class Service::SAPDshell < Service::HttpPost :email => 'dshell@sap.com' - def receive_push + def receive_event # Check for settings - if data['dshell_url'].to_s.empty? + if required_config_value('dshell_url').to_s.empty? raise_config_error "SAP Dshell URL not set" end - if data['user_id'].to_s.empty? + if required_config_value('user_id').to_s.empty? raise_config_error "User id not set" end - if data['password'].to_s.empty? + if required_config_value('password').to_s.empty? raise_config_error "Password not set" end # Sets this basic auth info for every request. - http.basic_auth(data['user_id'], data['password']) + http.basic_auth( required_config_value('user_id'), required_config_value('password')) http.headers['Content-Type'] = 'application/json' @@ -38,11 +38,12 @@ def receive_push l_repository = payload['repository']['url'].to_s - l_dshell_url = data['dshell_url'] + l_dshell_url = required_config_value('dshell_url') l_call_url = "#{l_dshell_url}/?repo=#{l_repository}" - - res = http_post l_call_url, generate_json(payload) + + res = deliver l_call_url + if res.status < 200 || res.status > 299 raise_config_error "Failed with #{res.status}"