diff options
-rw-r--r-- | lib/api/builds.rb | 50 | ||||
-rw-r--r-- | lib/api/helpers.rb | 4 | ||||
-rw-r--r-- | spec/requests/builds_spec.rb | 74 |
3 files changed, 106 insertions, 22 deletions
diff --git a/lib/api/builds.rb b/lib/api/builds.rb index a77c63d..0982d7d 100644 --- a/lib/api/builds.rb +++ b/lib/api/builds.rb @@ -2,9 +2,7 @@ module API # Builds API class Builds < Grape::API resource :builds do - before { authenticate_runner! } - - # Runs oldest pending build by runner + # Runs oldest pending build by runner - Runners only # # Parameters: # token (required) - The uniq token of runner @@ -12,6 +10,7 @@ module API # Example Request: # POST /builds/register post "register" do + authenticate_runner! required_attributes! [:token] ActiveRecord::Base.transaction do @@ -28,7 +27,7 @@ module API end end - # Update an existing build + # Update an existing build - Runners only # # Parameters: # id (required) - The ID of a project @@ -37,6 +36,7 @@ module API # Example Request: # PUT /builds/:id put ":id" do + authenticate_runner! build = Build.where(runner_id: current_runner.id).running.find(params[:id]) build.update_attributes(trace: params[:trace]) @@ -47,6 +47,48 @@ module API build.drop end end + + # Create a build + # + # Parameters: + # project_id (required) - The ID of a project + # project_token (requires) - Project token + # data (required) - GitLab push data + # + # Sample GitLab push data: + # { + # "before": "95790bf891e76fee5e1747ab589903a6a1f80f22", + # "after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + # "ref": "refs/heads/master", + # "commits": [ + # { + # "id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", + # "message": "Update Catalan translation to e38cb41.", + # "timestamp": "2011-12-12T14:27:31+02:00", + # "url": "http://localhost/diaspora/commits/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", + # "author": { + # "name": "Jordi Mallach", + # "email": "jordi@softcatala.org", + # } + # }, .... more commits + # ] + # } + # + # Example Request: + # POST /builds + post do + required_attributes! [:project_id, :data, :project_token] + project = Project.find(params[:project_id]) + authenticate_project_token!(project) + build = project.register_build(params[:data]) + + if build.persisted? + present build, with: Entities::Build + else + errors = build.errors.full_messages.join(", ") + render_api_error!(errors, 400) + end + end end end end diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 4bea5a2..28a3f2b 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -29,6 +29,10 @@ module API forbidden! unless current_runner end + def authenticate_project_token!(project) + forbidden! unless project.valid_token?(params[:project_token]) + end + # Checks the occurrences of required attributes, each attribute must be present in the params hash # or a Bad Request error is invoked. # diff --git a/spec/requests/builds_spec.rb b/spec/requests/builds_spec.rb index 7db7823..26b21b2 100644 --- a/spec/requests/builds_spec.rb +++ b/spec/requests/builds_spec.rb @@ -6,34 +6,72 @@ describe API::API do let(:runner) { FactoryGirl.create(:runner) } let(:project) { FactoryGirl.create(:project) } - before do - FactoryGirl.create :runner_project, project_id: project.id, runner_id: runner.id - end + describe "Builds API for runners" do + before do + FactoryGirl.create :runner_project, project_id: project.id, runner_id: runner.id + end - describe "POST /builds/register" do - it "should start a build" do - build = FactoryGirl.create(:build, project_id: project.id, status: 'pending' ) + describe "POST /builds/register" do + it "should start a build" do + build = FactoryGirl.create(:build, project_id: project.id, status: 'pending' ) - post api("/builds/register"), token: runner.token + post api("/builds/register"), token: runner.token - response.status.should == 201 - json_response['sha'].should == build.sha + response.status.should == 201 + json_response['sha'].should == build.sha + end + + it "should return 404 error if no pending build found" do + post api("/builds/register"), token: runner.token + + response.status.should == 404 + end end - it "should return 404 error if no pending build found" do - post api("/builds/register"), token: runner.token + describe "PUT /builds/:id" do + let(:build) { FactoryGirl.create(:build, project_id: project.id, runner_id: runner.id) } - response.status.should == 404 + it "should update a running build" do + build.run! + put api("/builds/#{build.id}"), token: runner.token + response.status.should == 200 + end end end - describe "PUT /builds/:id" do - let(:build) { FactoryGirl.create(:build, project_id: project.id, runner_id: runner.id) } + describe "POST /builds" do + let(:data) { + { + "before" => "95790bf891e76fee5e1747ab589903a6a1f80f22", + "after" => "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "ref" => "refs/heads/master", + "commits" => [ + { + "id" => "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", + "message" => "Update Catalan translation to e38cb41.", + "timestamp" => "2011-12-12T14:27:31+02:00", + "url" => "http://localhost/diaspora/commits/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", + "author" => { + "name" => "Jordi Mallach", + "email" => "jordi@softcatala.org", + } + } + ] + } + } + + it "should create a build" do + post api("/builds"), project_id: project.id, data: data, project_token: project.token + + response.status.should == 201 + json_response['sha'].should == "da1560886d4f094c3e6c9ef40349f7d38b5d27d7" + end + + it "should return 400 error if no data passed" do + post api("/builds"), project_id: project.id, project_token: project.token - it "should update a running build" do - build.run! - put api("/builds/#{build.id}"), token: runner.token - response.status.should == 200 + response.status.should == 400 + json_response['message'].should == "400 (Bad request) \"data\" not given" end end end |