From c658360e94ea31a411923dbd14591c41fbecffdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Thu, 31 Aug 2017 18:12:08 -0300 Subject: Support new /internal/pre-receive API endpoint for post-receive --- CHANGELOG | 1 + hooks/pre-receive | 11 ++++++- lib/gitlab_net.rb | 8 +++++ spec/gitlab_net_spec.rb | 26 ++++++++++++++++ spec/vcr_cassettes/pre-receive-not-found.yml | 42 +++++++++++++++++++++++++ spec/vcr_cassettes/pre-receive.yml | 46 ++++++++++++++++++++++++++++ 6 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 spec/vcr_cassettes/pre-receive-not-found.yml create mode 100644 spec/vcr_cassettes/pre-receive.yml diff --git a/CHANGELOG b/CHANGELOG index 495a24f..43d2612 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,5 @@ v5.9.0 + - Support new /internal/pre-receive API endpoint for post-receive operations - Support new /internal/post-receive API endpoint for post-receive operations - Support `redis` field on /internal/check API endpoint diff --git a/hooks/pre-receive b/hooks/pre-receive index e8e04d8..78ff991 100755 --- a/hooks/pre-receive +++ b/hooks/pre-receive @@ -9,9 +9,18 @@ protocol = ENV.delete('GL_PROTOCOL') repo_path = Dir.pwd gl_repository = ENV['GL_REPOSITORY'] +def increase_reference_counter(gl_repository) + result = GitlabNet.new.pre_receive(gl_repository) + + result['reference_counter_increased'] +rescue GitlabNet::NotFound + GitlabReferenceCounter.new(repo_path).increase +end + require_relative '../lib/gitlab_custom_hook' require_relative '../lib/gitlab_reference_counter' require_relative '../lib/gitlab_access' +require_relative '../lib/gitlab_net' # It's important that on pre-receive `increase_reference_counter` gets executed # last so that it only runs if everything else succeeded. On post-receive on the @@ -19,7 +28,7 @@ require_relative '../lib/gitlab_access' # and we don't want to skip it if the custom hook fails. if GitlabAccess.new(gl_repository, repo_path, key_id, refs, protocol).exec && GitlabCustomHook.new(repo_path, key_id).pre_receive(refs) && - GitlabReferenceCounter.new(repo_path).increase + increase_reference_counter(gl_repository) exit 0 else exit 1 diff --git a/lib/gitlab_net.rb b/lib/gitlab_net.rb index b48f655..de0cc57 100644 --- a/lib/gitlab_net.rb +++ b/lib/gitlab_net.rb @@ -126,6 +126,14 @@ class GitlabNet JSON.parse(resp.body) if resp.code == '200' end + def pre_receive(gl_repository) + resp = post("#{host}/pre_receive", gl_repository: gl_repository) + + raise NotFound if resp.code == '404' + + JSON.parse(resp.body) if resp.code == '200' + end + def redis_client redis_config = config.redis database = redis_config['database'] || 0 diff --git a/spec/gitlab_net_spec.rb b/spec/gitlab_net_spec.rb index cbcef90..c22540b 100644 --- a/spec/gitlab_net_spec.rb +++ b/spec/gitlab_net_spec.rb @@ -126,6 +126,32 @@ describe GitlabNet, vcr: true do end end + describe :pre_receive do + let(:gl_repository) { "project-1" } + let(:params) { { gl_repository: gl_repository } } + + subject { gitlab_net.pre_receive(gl_repository) } + + it 'sends the correct parameters and returns the request body parsed' do + Net::HTTP::Post.any_instance.should_receive(:set_form_data) + .with(hash_including(params)) + + VCR.use_cassette("pre-receive") { subject } + end + + it 'calls /internal/pre-receive' do + VCR.use_cassette("pre-receive") do + expect(subject['reference_counter_increased']).to be(true) + end + end + + it 'throws a NotFound error when pre-receive is not available' do + VCR.use_cassette("pre-receive-not-found") do + expect { subject }.to raise_error(GitlabNet::NotFound) + end + end + end + describe :post_receive do let(:gl_repository) { "project-1" } let(:changes) { "123456 789012 refs/heads/test\n654321 210987 refs/tags/tag" } diff --git a/spec/vcr_cassettes/pre-receive-not-found.yml b/spec/vcr_cassettes/pre-receive-not-found.yml new file mode 100644 index 0000000..5eed672 --- /dev/null +++ b/spec/vcr_cassettes/pre-receive-not-found.yml @@ -0,0 +1,42 @@ +--- +http_interactions: +- request: + method: post + uri: http://localhost:3000/api/v4/internal/pre_receive + body: + encoding: US-ASCII + string: gl_repository=project-1&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + Content-Type: + - application/x-www-form-urlencoded + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache + Content-Length: + - '25' + Content-Type: + - application/json + Date: + - Thu, 31 Aug 2017 16:41:13 GMT + Vary: + - Origin + X-Request-Id: + - 0b845e9a-5417-488d-bc5a-07d8c585b2da + X-Runtime: + - '0.295361' + body: + encoding: UTF-8 + string: '{"error":"404 Not Found"}' + http_version: + recorded_at: Thu, 31 Aug 2017 16:41:13 GMT +recorded_with: VCR 2.4.0 diff --git a/spec/vcr_cassettes/pre-receive.yml b/spec/vcr_cassettes/pre-receive.yml new file mode 100644 index 0000000..6072d0c --- /dev/null +++ b/spec/vcr_cassettes/pre-receive.yml @@ -0,0 +1,46 @@ +--- +http_interactions: +- request: + method: post + uri: http://localhost:3000/api/v4/internal/pre_receive + body: + encoding: US-ASCII + string: gl_repository=project-1&secret_token=0a3938d9d95d807e94d937af3a4fbbea%0A + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + Content-Type: + - application/x-www-form-urlencoded + response: + status: + code: 200 + message: OK + headers: + Cache-Control: + - max-age=0, private, must-revalidate + Content-Length: + - '36' + Content-Type: + - application/json + Date: + - Thu, 31 Aug 2017 20:17:41 GMT + Etag: + - W/"7d4df85c493bd3d421351aa791a8fbf6" + Vary: + - Origin + X-Frame-Options: + - SAMEORIGIN + X-Request-Id: + - f0c84103-8dc0-48ea-a142-62554f6bca3d + X-Runtime: + - '0.612997' + body: + encoding: UTF-8 + string: '{"reference_counter_increased":true}' + http_version: + recorded_at: Thu, 31 Aug 2017 20:17:41 GMT +recorded_with: VCR 2.4.0 -- cgit v1.2.1