diff --git a/Gemfile.lock b/Gemfile.lock index 1fd8a971..064187b1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -426,6 +426,3 @@ DEPENDENCIES travis-yaml! unicorn yard-sinatra! - -BUNDLED WITH - 1.11.2 diff --git a/lib/travis/api/app/endpoint/builds.rb b/lib/travis/api/app/endpoint/builds.rb index 91d375dc..ffa6b90a 100644 --- a/lib/travis/api/app/endpoint/builds.rb +++ b/lib/travis/api/app/endpoint/builds.rb @@ -1,6 +1,7 @@ require 'travis/api/app' require 'travis/api/workers/build_cancellation' require 'travis/api/workers/build_restart' +require 'travis/api/enqueue/services/enqueue_build' class Travis::Api::App class Endpoint @@ -48,16 +49,29 @@ class Travis::Api::App post '/:id/restart' do Metriks.meter("api.request.restart_build").mark - - service = self.service(:reset_model, build_id: params[:id]) - if !service.accept? - status 400 - result = false + if Travis::Features.owner_active?(:enqueue_to_hub, current_user) + service = Travis::Enqueue::Services::EnqueueBuild.new(current_user, params[:id]) + if !service.accept? + status 400 + result = false + else + payload = {id: params[:id], user_id: current_user.id} + service.push("build:restart", payload) + status 202 + result = true + end else - Travis::Sidekiq::BuildRestart.perform_async(id: params[:id], user_id: current_user.id) - status 202 - result = true + service = self.service(:reset_model, build_id: params[:id]) + if !service.accept? + status 400 + result = false + else + Travis::Sidekiq::BuildRestart.perform_async(id: params[:id], user_id: current_user.id) + status 202 + result = true + end end + respond_with(result: result, flash: service.messages) end end diff --git a/lib/travis/api/enqueue/services/enqueue_build.rb b/lib/travis/api/enqueue/services/enqueue_build.rb new file mode 100644 index 00000000..8776a5e6 --- /dev/null +++ b/lib/travis/api/enqueue/services/enqueue_build.rb @@ -0,0 +1,49 @@ +module Travis + module Enqueue + module Services + + class EnqueueBuild + attr_reader :current_user, :build + + def initialize(current_user, build_id) + @current_user = current_user + @build = Build.find(build_id) + end + + def push(event, payload) + ::Sidekiq::Client.push( + 'queue' => 'hub', + 'class' => 'Travis::Hub::Sidekiq::Worker', + 'args' => [event, payload] + ) + end + + def accept? + current_user && permission? && resetable? + end + + def messages + messages = [] + messages << { notice: "The build was successfully restarted." } if accept? + messages << { error: 'You do not seem to have sufficient permissions.' } unless permission? + messages << { error: "This build currently can not be restarted." } unless resetable? + messages + end + + private + + def permission? + current_user.permission?(required_role, repository_id: build.repository_id) + end + + def resetable? + build.resetable? + end + + def required_role + Travis.config.roles.reset_model + end + end + end + end +end diff --git a/spec/integration/v2/builds_spec.rb b/spec/integration/v2/builds_spec.rb index e36aeeb2..98a57e26 100644 --- a/spec/integration/v2/builds_spec.rb +++ b/spec/integration/v2/builds_spec.rb @@ -113,22 +113,42 @@ describe 'Builds' do context 'when build passed' do before do - Travis::Sidekiq::BuildCancellation.stubs(:perform_async) build.matrix.each { |j| j.update_attribute(:state, 'passed') } build.update_attribute(:state, 'passed') end - it 'restarts the build' do - Travis::Sidekiq::BuildRestart.expects(:perform_async).with(id: build.id.to_s, user_id: user.id) - response = post "/builds/#{build.id}/restart", {}, headers - response.status.should == 202 + describe 'Enqueues restart event to the Hub' do + before { Travis::Features.activate_owner(:enqueue_to_hub, repo.owner) } + + it 'restarts the build' do + ::Sidekiq::Client.expects(:push) + response = post "/builds/#{build.id}/restart", {}, headers + response.status.should == 202 + end + + it 'sends the correct response body' do + ::Sidekiq::Client.expects(:push) + response = post "/builds/#{build.id}/restart", {}, headers + body = JSON.parse(response.body) + body.should == {"result"=>true, "flash"=>[{"notice"=>"The build was successfully restarted."}]} + end end - it 'sends the correct response body' do - Travis::Sidekiq::BuildRestart.expects(:perform_async).with(id: build.id.to_s, user_id: user.id) - response = post "/builds/#{build.id}/restart", {}, headers - body = JSON.parse(response.body) - body.should == {"result"=>true, "flash"=>[{"notice"=>"The build was successfully restarted."}]} + describe 'Restart from the Core' do + before { Travis::Sidekiq::BuildRestart.stubs(:perform_async) } + + it 'restarts the build' do + Travis::Sidekiq::BuildRestart.expects(:perform_async).with(id: build.id.to_s, user_id: user.id) + response = post "/builds/#{build.id}/restart", {}, headers + response.status.should == 202 + end + + it 'sends the correct response body' do + Travis::Sidekiq::BuildRestart.expects(:perform_async).with(id: build.id.to_s, user_id: user.id) + response = post "/builds/#{build.id}/restart", {}, headers + body = JSON.parse(response.body) + body.should == {"result"=>true, "flash"=>[{"notice"=>"The build was successfully restarted."}]} + end end end end