Commit 3d9ce37a authored by Kamil Trzcinski's avatar Kamil Trzcinski

Reimplement Trigger API

parent 64bfd9d7
module TriggersHelper module TriggersHelper
def ci_build_trigger_url(project_id, ref_name) def builds_trigger_url(project_id)
"#{Settings.gitlab_ci.url}/ci/api/v1/projects/#{project_id}/refs/#{ref_name}/trigger" "#{Settings.gitlab.url}/api/v3/projects/#{project_id}/trigger/builds"
end end
end end
...@@ -36,7 +36,8 @@ ...@@ -36,7 +36,8 @@
:plain :plain
curl -X POST \ curl -X POST \
-F token=TOKEN \ -F token=TOKEN \
#{ci_build_trigger_url(@project.id, 'REF_NAME')} -F ref=REF_NAME \
#{builds_trigger_url(@project.id)}
%h3 %h3
Use .gitlab-ci.yml Use .gitlab-ci.yml
...@@ -51,7 +52,7 @@ ...@@ -51,7 +52,7 @@
trigger: trigger:
type: deploy type: deploy
script: script:
- "curl -X POST -F token=TOKEN #{ci_build_trigger_url(@project.id, 'REF_NAME')}" - "curl -X POST -F token=TOKEN -F ref=REF_NAME #{builds_trigger_url(@project.id)}"
%h3 %h3
Pass build variables Pass build variables
...@@ -65,5 +66,6 @@ ...@@ -65,5 +66,6 @@
:plain :plain
curl -X POST \ curl -X POST \
-F token=TOKEN \ -F token=TOKEN \
-F "ref=REF_NAME" \
-F "variables[RUN_NIGHTLY_BUILD]=true" \ -F "variables[RUN_NIGHTLY_BUILD]=true" \
#{ci_build_trigger_url(@project.id, 'REF_NAME')} #{builds_trigger_url(@project.id, 'TOKEN')}
...@@ -53,5 +53,6 @@ module API ...@@ -53,5 +53,6 @@ module API
mount Settings mount Settings
mount Keys mount Keys
mount Tags mount Tags
mount Triggers
end end
end end
...@@ -361,5 +361,9 @@ module API ...@@ -361,5 +361,9 @@ module API
end end
end end
end end
class TriggerRequest < Grape::Entity
expose :id, :variables
end
end end
end end
module API
# Triggers API
class Triggers < Grape::API
resource :projects do
# Trigger a GitLab project build
#
# Parameters:
# id (required) - The ID of a CI project
# ref (required) - The name of project's branch or tag
# token (required) - The uniq token of trigger
# variables (optional) - The list of variables to be injected into build
# Example Request:
# POST /projects/:id/trigger/builds
post ":id/trigger/builds" do
required_attributes! [:ref, :token]
project = Project.find_with_namespace(id) || Project.find_by(id: params[:id])
trigger = Ci::Trigger.find_by_token(params[:token].to_s)
not_found! unless project && trigger
unauthorized! unless trigger.project == project
# validate variables
variables = params[:variables]
if variables
unless variables.is_a?(Hash)
render_api_error!('variables needs to be a hash', 400)
end
unless variables.all? { |key, value| key.is_a?(String) && value.is_a?(String) }
render_api_error!('variables needs to be a map of key-valued strings', 400)
end
# convert variables from Mash to Hash
variables = variables.to_h
end
# create request and trigger builds
trigger_request = Ci::CreateTriggerRequestService.new.execute(project, trigger, params[:ref].to_s, variables)
if trigger_request
present trigger_request, with: Entities::TriggerRequest
else
errors = 'No builds created'
render_api_error!(errors, 400)
end
end
end
end
end
require 'spec_helper'
describe API::API do
include ApiHelpers
describe 'POST /projects/:project_id/trigger' do
let!(:trigger_token) { 'secure token' }
let!(:project) { FactoryGirl.create(:project) }
let!(:project2) { FactoryGirl.create(:empty_project) }
let!(:trigger) { FactoryGirl.create(:ci_trigger, project: project, token: trigger_token) }
let(:options) do
{
token: trigger_token
}
end
before do
stub_ci_commit_to_return_yaml_file
end
context 'Handles errors' do
it 'should return bad request if token is missing' do
post api("/projects/#{project.id}/trigger/builds"), ref: 'master'
expect(response.status).to eq(400)
end
it 'should return not found if project is not found' do
post api('/projects/0/refs/master/trigger/builds'), options.merge(ref: 'master')
expect(response.status).to eq(404)
end
it 'should return unauthorized if token is for different project' do
post api("/projects/#{project2.id}/trigger/builds"), options.merge(ref: 'master')
expect(response.status).to eq(401)
end
end
context 'Have a commit' do
let(:commit) { project.ci_commits.last }
it 'should create builds' do
post api("/projects/#{project.id}/trigger/builds"), options.merge(ref: 'master')
expect(response.status).to eq(201)
commit.builds.reload
expect(commit.builds.size).to eq(2)
end
it 'should return bad request with no builds created if there\'s no commit for that ref' do
post api("/projects/#{project.id}/trigger/builds"), options.merge(ref: 'other-branch')
expect(response.status).to eq(400)
expect(json_response['message']).to eq('No builds created')
end
context 'Validates variables' do
let(:variables) do
{ 'TRIGGER_KEY' => 'TRIGGER_VALUE' }
end
it 'should validate variables to be a hash' do
post api("/projects/#{project.id}/trigger/builds"), options.merge(variables: 'value', refs: 'master')
expect(response.status).to eq(400)
expect(json_response['message']).to eq('variables needs to be a hash')
end
it 'should validate variables needs to be a map of key-valued strings' do
post api("/projects/#{project.id}/trigger/builds"), options.merge(variables: { key: %w(1 2) }, refs: 'master')
expect(response.status).to eq(400)
expect(json_response['message']).to eq('variables needs to be a map of key-valued strings')
end
it 'create trigger request with variables' do
post api("/projects/#{project.id}/trigger/builds"), options.merge(variables: variables, refs: 'master')
expect(response.status).to eq(201)
commit.builds.reload
expect(commit.builds.first.trigger_request.variables).to eq(variables)
end
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment