From f19de9d134ae8ee42554842d3610c1ff6ba740cf Mon Sep 17 00:00:00 2001 From: Piotr Sarnacki Date: Thu, 8 Aug 2013 14:25:20 +0200 Subject: [PATCH 1/2] Implement jobs/:id/cancel and builds/:id/cancel endpoints --- Gemfile | 2 +- Gemfile.lock | 3 +- lib/travis/api/app/endpoint/builds.rb | 21 +++++++++++++ lib/travis/api/app/endpoint/jobs.rb | 21 +++++++++++++ spec/integration/v2/builds_spec.rb | 43 +++++++++++++++++++++++++++ spec/integration/v2/jobs_spec.rb | 42 ++++++++++++++++++++++++++ 6 files changed, 130 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 4ebc17f3..aa3d5661 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ ruby '1.9.3' rescue nil source 'https://rubygems.org' gemspec -gem 'travis-core', github: 'travis-ci/travis-core' +gem 'travis-core', github: 'travis-ci/travis-core', branch: 'ps-cancel' gem 'travis-support', github: 'travis-ci/travis-support' gem 'travis-sidekiqs', github: 'travis-ci/travis-sidekiqs', require: nil, ref: 'cde9741' gem 'sinatra' diff --git a/Gemfile.lock b/Gemfile.lock index 139f61d9..8de84c79 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -31,7 +31,8 @@ GIT GIT remote: git://github.com/travis-ci/travis-core.git - revision: 0a194c97c857a39c03a5a02eec283e751099d402 + revision: fa4e4051d35da428d9d67e1c2e2230568f3c2653 + branch: ps-cancel specs: travis-core (0.0.1) actionmailer (~> 3.2.12) diff --git a/lib/travis/api/app/endpoint/builds.rb b/lib/travis/api/app/endpoint/builds.rb index f956c7ad..98395afc 100644 --- a/lib/travis/api/app/endpoint/builds.rb +++ b/lib/travis/api/app/endpoint/builds.rb @@ -12,6 +12,27 @@ class Travis::Api::App get '/:id' do respond_with service(:find_build, params) end + + post '/:id/cancel' do + service = self.service(:cancel_build, params) + if !service.authorized? + json = { error: { + message: "You don't have access to cancel build(#{params[:id]})" + } } + status 403 + respond_with json + elsif !service.can_cancel? + json = { error: { + message: "The build(#{params[:id]}) can't be canceled", + code: 'cant_cancel' + } } + status 422 + respond_with json + else + service.run + status 204 + end + end end end end diff --git a/lib/travis/api/app/endpoint/jobs.rb b/lib/travis/api/app/endpoint/jobs.rb index 966ef7cd..2ac3ba94 100644 --- a/lib/travis/api/app/endpoint/jobs.rb +++ b/lib/travis/api/app/endpoint/jobs.rb @@ -36,5 +36,26 @@ class Travis::Api::App "#{name}#{'-staging' if Travis.env == 'staging'}.#{Travis.config.host.split('.')[-2, 2].join('.')}" end end + + post '/:id/cancel' do + service = self.service(:cancel_job, params) + if !service.authorized? + json = { error: { + message: "You don't have access to cancel job(#{params[:id]})" + } } + status 403 + respond_with json + elsif !service.can_cancel? + json = { error: { + message: "The job(#{params[:id]}) can't be canceled", + code: 'cant_cancel' + } } + status 422 + respond_with json + else + service.run + status 204 + end + end end end diff --git a/spec/integration/v2/builds_spec.rb b/spec/integration/v2/builds_spec.rb index 8410374f..325ece4f 100644 --- a/spec/integration/v2/builds_spec.rb +++ b/spec/integration/v2/builds_spec.rb @@ -46,4 +46,47 @@ describe 'Builds' do response = get "/builds?repository_id=#{repo.id}&branches=true", {}, headers response.should deliver_json_for(repo.last_finished_builds_by_branches, version: 'v2') end + + describe 'POST /builds/:id/cancel' do + let(:user) { User.where(login: 'svenfuchs').first } + let(:token) { Travis::Api::App::AccessToken.create(user: user, app_id: -1) } + + before { + headers.merge! 'HTTP_AUTHORIZATION' => "token #{token}" + user.permissions.create!(repository_id: build.repository.id, :push => true) + } + + context 'when user does not have rights to cancel the build' do + before { user.permissions.destroy_all } + + it 'responds with 403' do + response = post "/builds/#{build.id}/cancel", {}, headers + response.status.should == 403 + end + end + + context 'when build is not cancelable' do + before { build.matrix.each { |j| j.update_attribute(:state, 'passed') } } + + it 'responds with 422' do + response = post "/builds/#{build.id}/cancel", {}, headers + response.status.should == 422 + end + end + + context 'when build can be canceled' do + it 'cancels the build and responds with 204' do + build.matrix.each { |j| j.update_attribute(:state, 'created') } + build.update_attribute(:state, 'created') + + response = nil + expect { + response = post "/builds/#{build.id}/cancel", {}, headers + }.to change { build.reload.state } + response.status.should == 204 + + build.state.should == 'canceled' + end + end + end end diff --git a/spec/integration/v2/jobs_spec.rb b/spec/integration/v2/jobs_spec.rb index 4c7d202e..8dcc7a0c 100644 --- a/spec/integration/v2/jobs_spec.rb +++ b/spec/integration/v2/jobs_spec.rb @@ -75,4 +75,46 @@ describe 'Jobs' do end end end + + describe 'POST /jobs/:id/cancel' do + let(:user) { User.where(login: 'svenfuchs').first } + let(:token) { Travis::Api::App::AccessToken.create(user: user, app_id: -1) } + + before { + headers.merge! 'HTTP_AUTHORIZATION' => "token #{token}" + user.permissions.create!(repository_id: job.repository.id, :push => true) + } + + context 'when user does not have rights to cancel the job' do + before { user.permissions.destroy_all } + + it 'responds with 403' do + response = post "/jobs/#{job.id}/cancel", {}, headers + response.status.should == 403 + end + end + + context 'when job is not cancelable' do + before { job.update_attribute(:state, 'passed') } + + it 'responds with 422' do + response = post "/jobs/#{job.id}/cancel", {}, headers + response.status.should == 422 + end + end + + context 'when job can be canceled' do + it 'cancels the job and responds with 204' do + job.update_attribute(:state, 'created') + + response = nil + expect { + response = post "/jobs/#{job.id}/cancel", {}, headers + }.to change { job.reload.state } + response.status.should == 204 + + job.state.should == 'canceled' + end + end + end end From 6910d6f243ce21d6196c3d5455cc05b5fc92e7f0 Mon Sep 17 00:00:00 2001 From: Piotr Sarnacki Date: Fri, 9 Aug 2013 17:55:59 +0200 Subject: [PATCH 2/2] Bump travis-core (use master branch) --- Gemfile | 2 +- Gemfile.lock | 47 +++++++++++++++++++++++------------------------ 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/Gemfile b/Gemfile index aa3d5661..4ebc17f3 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ ruby '1.9.3' rescue nil source 'https://rubygems.org' gemspec -gem 'travis-core', github: 'travis-ci/travis-core', branch: 'ps-cancel' +gem 'travis-core', github: 'travis-ci/travis-core' gem 'travis-support', github: 'travis-ci/travis-support' gem 'travis-sidekiqs', github: 'travis-ci/travis-sidekiqs', require: nil, ref: 'cde9741' gem 'sinatra' diff --git a/Gemfile.lock b/Gemfile.lock index 8de84c79..c2466d33 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -31,8 +31,7 @@ GIT GIT remote: git://github.com/travis-ci/travis-core.git - revision: fa4e4051d35da428d9d67e1c2e2230568f3c2653 - branch: ps-cancel + revision: 9adeb30c03674452d09fc551f5e61d40e70e6c72 specs: travis-core (0.0.1) actionmailer (~> 3.2.12) @@ -90,12 +89,12 @@ PATH GEM remote: https://rubygems.org/ specs: - actionmailer (3.2.13) - actionpack (= 3.2.13) - mail (~> 2.5.3) - actionpack (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) + actionmailer (3.2.14) + actionpack (= 3.2.14) + mail (~> 2.5.4) + actionpack (3.2.14) + activemodel (= 3.2.14) + activesupport (= 3.2.14) builder (~> 3.0.0) erubis (~> 2.7.0) journey (~> 1.0.4) @@ -103,20 +102,20 @@ GEM rack-cache (~> 1.2) rack-test (~> 0.6.1) sprockets (~> 2.2.1) - activemodel (3.2.13) - activesupport (= 3.2.13) + activemodel (3.2.14) + activesupport (= 3.2.14) builder (~> 3.0.0) - activerecord (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) + activerecord (3.2.14) + activemodel (= 3.2.14) + activesupport (= 3.2.14) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activesupport (3.2.13) - i18n (= 0.6.1) + activesupport (3.2.14) + i18n (~> 0.6, >= 0.6.4) multi_json (~> 1.0) addressable (2.3.5) arel (3.0.2) - atomic (1.1.10) + atomic (1.1.12) avl_tree (1.1.3) backports (2.8.2) builder (3.0.4) @@ -140,8 +139,8 @@ GEM facter (1.7.2) factory_girl (2.4.2) activesupport - faraday (0.8.7) - multipart-post (~> 1.1) + faraday (0.8.8) + multipart-post (~> 1.2.0) ffi (1.9.0) foreman (0.63.0) dotenv (>= 0.7) @@ -157,7 +156,7 @@ GEM hashr (0.0.22) hike (1.2.3) hitimes (1.2.1) - i18n (0.6.1) + i18n (0.6.5) journey (1.0.4) json (1.8.0) listen (1.2.2) @@ -176,9 +175,9 @@ GEM mime-types (1.23) mocha (0.14.0) metaclass (~> 0.0.1) - multi_json (1.7.7) + multi_json (1.7.9) multipart-post (1.2.0) - net-http-persistent (2.8) + net-http-persistent (2.9) net-http-pipeline (1.0.1) newrelic_rpm (3.6.1.88) pg (0.13.2) @@ -203,9 +202,9 @@ GEM rack rack-test (0.6.2) rack (>= 1.0) - railties (3.2.13) - actionpack (= 3.2.13) - activesupport (= 3.2.13) + railties (3.2.14) + actionpack (= 3.2.14) + activesupport (= 3.2.14) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4)